Bläddra i källkod

封装了table表格以及抽屉、设置element为中文

@sun-chaoqun 2 år sedan
förälder
incheckning
a860a35a1a

+ 11 - 0
components.d.ts

@@ -10,10 +10,18 @@ export {}
 declare module '@vue/runtime-core' {
   export interface GlobalComponents {
     404: typeof import('./src/components/ErrorMessage/404.vue')['default']
+    Dialog: typeof import('./src/components/Dialog/index.vue')['default']
+    Drawer: typeof import('./src/components/Drawer/index.vue')['default']
     ElAside: typeof import('element-plus/es')['ElAside']
     ElButton: typeof import('element-plus/es')['ElButton']
     ElCard: typeof import('element-plus/es')['ElCard']
+    ElCol: typeof import('element-plus/es')['ElCol']
     ElContainer: typeof import('element-plus/es')['ElContainer']
+    ElDialog: typeof import('element-plus/es')['ElDialog']
+    ElDrawer: typeof import('element-plus/es')['ElDrawer']
+    ElDropdown: typeof import('element-plus/es')['ElDropdown']
+    ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
+    ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu']
     ElEmpty: typeof import('element-plus/es')['ElEmpty']
     ElForm: typeof import('element-plus/es')['ElForm']
     ElFormItem: typeof import('element-plus/es')['ElFormItem']
@@ -24,8 +32,11 @@ declare module '@vue/runtime-core' {
     ElMenu: typeof import('element-plus/es')['ElMenu']
     ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
     ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup']
+    ElOption: typeof import('element-plus/es')['ElOption']
     ElPagination: typeof import('element-plus/es')['ElPagination']
+    ElRow: typeof import('element-plus/es')['ElRow']
     ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
+    ElSelect: typeof import('element-plus/es')['ElSelect']
     ElSubMenu: typeof import('element-plus/es')['ElSubMenu']
     ElTable: typeof import('element-plus/es')['ElTable']
     ElTableColumn: typeof import('element-plus/es')['ElTableColumn']

+ 10 - 11
index.html

@@ -35,8 +35,8 @@
           position: relative;
           box-sizing: border-box;
           display: inline-block;
-          width: 32px;
-          height: 32px;
+          width: 128px;
+          height: 128px;
           font-size: 32px;
           transform: rotate(45deg);
           animation: ant-rotate 1.2s infinite linear;
@@ -44,8 +44,8 @@
         .dot i {
           position: absolute;
           display: block;
-          width: 14px;
-          height: 14px;
+          width: 56px;
+          height: 56px;
           background-color: #409eff;
           border-radius: 100%;
           opacity: 0.3;
@@ -90,13 +90,12 @@
       </div>
     </div>
     <script>
-      const color = "#22c1c3";
-      const isDark = JSON.parse(window.localStorage.getItem("GlobalState"))
-        ?.themeConfig?.isDark;
-      const dot = document.querySelectorAll(".dot i");
-      const html = document.querySelector("html");
-      dot.forEach((item) => (item.style.background = color));
-      if (isDark) html.style.background = "#141414";
+      const color = '#22c1c3'
+      const isDark = JSON.parse(window.localStorage.getItem('GlobalState'))?.themeConfig?.isDark
+      const dot = document.querySelectorAll('.dot i')
+      const html = document.querySelector('html')
+      dot.forEach(item => (item.style.background = color))
+      if (isDark) html.style.background = '#141414'
     </script>
     <script type="module" src="/src/main.ts"></script>
   </body>

+ 7 - 2
src/App.vue

@@ -1,7 +1,12 @@
-<script setup lang="ts"></script>
+<script setup lang="ts">
+import { ElConfigProvider } from 'element-plus'
+import zh from 'element-plus/lib/locale/lang/zh-cn'
+</script>
 
 <template>
-  <router-view></router-view>
+  <ElConfigProvider :locale="zh">
+    <router-view></router-view>
+  </ElConfigProvider>
 </template>
 
 <style scoped></style>

+ 2 - 2
src/api/http.ts

@@ -6,7 +6,7 @@ interface RequestInterceptors {
   requestInterceptors?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig
   requestInterceptorsCatch?: (err: any) => any
   // 响应拦截
-  responseInterceptors?: (config: AxiosResponse) => AxiosResponse
+  responseInterceptors?: <T = AxiosResponse>(config: T) => T
   responseInterceptorsCatch?: (err: any) => any
 }
 // 自定义传入的参数
@@ -54,7 +54,7 @@ class Request {
     return new Promise((resolve, reject) => {
       // 如果我们为单个请求设置拦截器,这里使用单个请求的拦截器
       if (config.interceptors?.requestInterceptors) {
-        config = config.interceptors.requestInterceptors(config)
+        config = config.interceptors.requestInterceptors(config as InternalAxiosRequestConfig)
       }
       this.instance
         .request<any, T>(config)

+ 21 - 0
src/components/Dialog/index.vue

@@ -0,0 +1,21 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+const dialogTableVisible = ref(true)
+</script>
+
+<template>
+  <el-dialog v-model="dialogTableVisible" title="Shipping address">
+    <!-- 默认插槽 -->
+    <solt></solt>
+    <!-- 弹框头部 -->
+    <template #title>
+      <slot name="title"></slot>
+    </template>
+    <!-- 弹框页脚 -->
+    <template #footer>
+      <slot name="footer"></slot>
+    </template>
+  </el-dialog>
+</template>
+
+<style scoped></style>

+ 42 - 0
src/components/Drawer/index.vue

@@ -0,0 +1,42 @@
+<script setup lang="ts">
+import { ref } from 'vue'
+const visible = ref(false)
+const drawerRef = ref(null)
+
+type Fn = () => void
+interface drawerProps {
+  title?: string
+  handleClose?: (params: Fn) => void
+  direction: string
+}
+
+withDefaults(defineProps<drawerProps>(), {
+  title: '',
+  direction: 'rtl' // rtl / ltr / ttb / btt
+})
+
+const closeDrawer = () => (visible.value = true)
+defineExpose({ closeDrawer })
+</script>
+
+<template>
+  <div>
+    <el-drawer
+      ref="drawerRef"
+      v-model="visible"
+      :title="title"
+      :before-close="handleClose"
+      :direction="direction"
+      class="demo-drawer"
+    >
+      <template #header="{ close, titleId, titleClass }">
+        <slot name="header" :params="{ close, titleId, titleClass }"></slot>
+      </template>
+      <div class="demo-drawer__content">
+        <slot></slot>
+      </div>
+    </el-drawer>
+  </div>
+</template>
+
+<style scoped></style>

+ 1 - 1
src/components/TableBase/components/Pagination.vue

@@ -20,7 +20,7 @@ defineProps<PaginationProps>()
     <el-pagination
       :current-page="pageable.pageNum"
       :page-size="pageable.pageSize"
-      :page-sizes="[100, 200, 300, 400]"
+      :page-sizes="[10, 20, 50, 100]"
       :small="pageable.small"
       :disabled="pageable.disabled"
       :background="true"

+ 4 - 0
src/components/TableBase/index.scss

@@ -4,6 +4,10 @@
   margin-bottom: 1rem;
   border: 1px solid var(--el-border-color-light);
   border-radius: 4px;
+  padding: 20px;
+
+  display: flex;
+  align-items: center;
 }
 
 .table-header,

+ 3 - 1
src/components/TableBase/index.vue

@@ -49,7 +49,9 @@ console.log(tableData, tableColumns)
 </script>
 
 <template>
-  <div class="table-header"></div>
+  <div class="table-header">
+    <slot name="table-header"></slot>
+  </div>
 
   <div class="card table">
     <el-table :data="tableData">

+ 32 - 0
src/layouts/Header/index.vue

@@ -0,0 +1,32 @@
+<script setup lang="ts"></script>
+
+<template>
+  <div class="header">
+    <el-row>
+      <el-col :span="12"
+        ><div class="grid-content ep-bg-purple" />
+        123</el-col
+      >
+      <el-col :span="4" :offset="8">
+        <el-dropdown>
+          <el-button type="primary">
+            退出登录<el-icon class="el-icon--right"><arrow-down /></el-icon>
+          </el-button>
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item>退出登录</el-dropdown-item>
+              <el-dropdown-item>Action 2</el-dropdown-item>
+              <el-dropdown-item>Action 3</el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<style scoped lang="scss">
+.header {
+  width: 100%;
+}
+</style>

+ 16 - 0
src/layouts/Main/index.scss

@@ -7,3 +7,19 @@
     background-color: #f0f2f5;
   }
 }
+
+/* fade-transform */
+.fade-transform-leave-active,
+.fade-transform-enter-active {
+  transition: all 0.2s;
+}
+.fade-transform-enter-from {
+  // opacity: 0;
+  transition: all 0.2s;
+  transform: translateX(-30px);
+}
+.fade-transform-leave-to {
+  // opacity: 0;
+  transition: all 0.2s;
+  transform: translateX(30px);
+}

+ 18 - 5
src/layouts/Main/index.vue

@@ -1,14 +1,27 @@
-<script setup lang="ts"></script>
+<script setup lang="ts">
+import { ref, provide } from 'vue'
+import { KeepAliveStore } from '@/stores/modules/keepAlive'
+const isRouterShow = ref(true)
+const refreshCurrentPage = (val: boolean) => {
+  console.log(val)
+  isRouterShow.value = val
+}
+provide('refresh', refreshCurrentPage)
+
+const keepAliveStore = KeepAliveStore()
+console.log(keepAliveStore)
+</script>
 
 <template>
   <el-main>
-    <router-view v-slot="{ Component, route }">
-      <transition appear name="fade-transform" mode="out-in">
+    <transition appear name="fade-transform" mode="out-in">
+      <router-view v-slot="{ Component, route }">
         <keep-alive>
           <component :is="Component" :key="route.path" />
         </keep-alive>
-      </transition>
-    </router-view>
+        <!-- </transition> -->
+      </router-view>
+    </transition>
   </el-main>
 </template>
 

+ 2 - 0
src/main.ts

@@ -1,6 +1,8 @@
 import { createApp } from 'vue'
 // 全局默认样式
 import './style.scss'
+// 覆盖element默认样式
+import '@/styles/element.scss'
 // 进度条样式
 import 'nprogress/nprogress.css'
 // element-ui样式

+ 25 - 0
src/stores/interface/index.ts

@@ -0,0 +1,25 @@
+/* GlobalState */
+export interface GlobalState {
+  token: string
+  userInfo: any
+  language?: string
+}
+
+/* tabsMenuProps */
+export interface TabsMenuProps {
+  icon: string
+  title: string
+  path: string
+  name: string
+  close: boolean
+}
+
+/* TabsState */
+export interface TabsState {
+  tabsMenuList: TabsMenuProps[]
+}
+
+/* keepAliveState */
+export interface keepAliveState {
+  keepAliveName: string[]
+}

+ 26 - 0
src/stores/modules/keepAlive.ts

@@ -0,0 +1,26 @@
+import { defineStore } from 'pinia'
+import { keepAliveState } from '@/stores/interface'
+
+// export const KeepAliveStore = 1212
+
+// KeepAliveStore
+export const KeepAliveStore = defineStore({
+  id: 'KeepAliveStore',
+  state: (): keepAliveState => ({
+    keepAliveName: []
+  }),
+  actions: {
+    // addKeepAliveName
+    async addKeepAliveName(name: string) {
+      !this.keepAliveName.includes(name) && this.keepAliveName.push(name)
+    },
+    // removeKeepAliveName
+    async removeKeepAliveName(name: string) {
+      this.keepAliveName = this.keepAliveName.filter(item => item !== name)
+    },
+    // setKeepAliveName
+    async setKeepAliveName(keepAliveName: string[] = []) {
+      this.keepAliveName = keepAliveName
+    }
+  }
+})

+ 4 - 0
src/styles/element.scss

@@ -7,3 +7,7 @@
   width: 100%;
   height: 100%;
 }
+
+.el-select {
+  width: 100%;
+}

+ 7 - 2
src/views/Index.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import SubMenu from '@/layouts/Menu/SubMenu.vue'
 import Main from '@/layouts/Main/index.vue'
+import Header from '@/layouts/Header/index.vue'
 const routerList = [
   {
     path: '/index',
@@ -137,10 +138,14 @@ const routerList = [
     </el-aside>
     <el-container>
       <el-header>
-        <div class="header-lf">header</div>
+        <Header />
       </el-header>
       <!-- <el-main>
-        <router-view></router-view>
+        <router-view v-slot="{ Component, route }">
+          <transition appear name="fade-transform" mode="out-in">
+            <component :is="Component" :key="route.path" />
+          </transition>
+        </router-view>
       </el-main> -->
       <Main />
     </el-container>

+ 81 - 2
src/views/account/roles/index.vue

@@ -2,6 +2,18 @@
 import TableBase from '@/components/TableBase/index.vue'
 import { ColumnProps } from '@/components/TableBase/interface/index'
 import { Edit, Delete } from '@element-plus/icons-vue'
+import Drawer from '@/components/Drawer/index.vue'
+import { ref, reactive } from 'vue'
+const drawerRef = ref()
+const action = ref(true)
+const formLabelWidth = ref('80px')
+const form = reactive({
+  username: '',
+  password: '',
+  user: '',
+  department: '',
+  post: ''
+})
 const columns: ColumnProps[] = [
   { type: 'index', label: '#', width: 80 },
   { prop: 'date', label: '时间', width: 120, search: { el: 'input' } },
@@ -28,20 +40,87 @@ const columns: ColumnProps[] = [
     fieldNames: { label: 'userLabel', value: 'userStatus' }
   },
   { prop: 'createTime', label: '创建时间', width: 180 },
-  { prop: 'operation', label: '操作', width: 430, fixed: 'right' }
+  { prop: 'operation', label: '操作', width: 200, fixed: 'right' }
 ]
 const requestApi = async () => {
   return false
 }
+
+const openDrawer = () => {
+  drawerRef.value.closeDrawer()
+  console.log(drawerRef.value)
+}
+
+type Fn = () => void
+const callbackDrawer = (done: Fn) => {
+  console.log('触发回调')
+  done()
+}
 </script>
 
 <template>
   <TableBase :columns="columns" :requestApi="requestApi">
+    <template #table-header>
+      <div class="input-suffix">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <span class="ml-3 w-35 text-gray-600 inline-flex items-center">账户查询:</span>
+            <el-input type="text" class="w-50 m-2" />
+            <el-button type="primary">搜索</el-button>
+          </el-col>
+          <el-col :span="6" :offset="6"><el-button type="primary" @click="openDrawer">添加</el-button></el-col>
+        </el-row>
+      </div>
+    </template>
     <template #right>
       <el-button link type="primary" size="small" :icon="Edit">编辑</el-button>
       <el-button link type="danger" size="small" :icon="Delete">删除</el-button>
     </template>
   </TableBase>
+  <Drawer ref="drawerRef" :handleClose="callbackDrawer">
+    <template #header="{ params }">
+      <h4 :id="params.titleId" :class="params.titleClass">{{ action ? '添加' : '编辑' }} - 账户管理</h4>
+    </template>
+    <el-form :model="form" class="form">
+      <el-form-item label="用户名:" :label-width="formLabelWidth">
+        <el-input v-model="form.username" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="密码:" :label-width="formLabelWidth">
+        <el-input v-model="form.username" autocomplete="off" />
+      </el-form-item>
+      <el-form-item label="角色名:" :label-width="formLabelWidth">
+        <el-select v-model="form.password" placeholder="请选择角色">
+          <el-option label="Area1" value="shanghai" />
+          <el-option label="Area2" value="beijing" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="部门:" :label-width="formLabelWidth">
+        <el-select v-model="form.password" placeholder="请选择部门">
+          <el-option label="Area1" value="shanghai" />
+          <el-option label="Area2" value="beijing" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="岗位:" :label-width="formLabelWidth">
+        <el-select v-model="form.password" placeholder="请选择岗位">
+          <el-option label="Area1" value="shanghai" />
+          <el-option label="Area2" value="beijing" />
+        </el-select>
+      </el-form-item>
+      <el-form-item :label-width="formLabelWidth">
+        <el-button color="#626aef">添加</el-button>
+      </el-form-item>
+    </el-form>
+  </Drawer>
 </template>
 
-<style scoped></style>
+<style scoped lang="scss">
+.input-suffix {
+  width: 100%;
+  .w-50 {
+    width: 12.5rem;
+  }
+}
+.form {
+  margin-top: 3rem;
+}
+</style>

+ 4 - 5
src/views/account/users/index.vue

@@ -1,13 +1,12 @@
 <script setup lang="ts">
-
+import Dialog from '@/components/Dialog/index.vue'
 </script>
 
 <template>
   <div class="role">
-    用户
+    <el-button type="primary">添加</el-button>
+    <Dialog />
   </div>
 </template>
 
-<style scoped>
-
-</style>
+<style scoped></style>