表格优化

This commit is contained in:
仲么了
2023-12-27 15:06:57 +08:00
parent d42936398e
commit b456881e6e
17 changed files with 115 additions and 74 deletions

View File

@@ -2,7 +2,7 @@
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> <link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>电能质量数据监测云平台</title> <title>电能质量数据监测云平台</title>
</head> </head>

View File

@@ -5,7 +5,7 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vue-tsc && vite build", "build": "vite build",
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
@@ -22,7 +22,9 @@
"pinia-plugin-persistedstate": "^3.2.1", "pinia-plugin-persistedstate": "^3.2.1",
"screenfull": "^6.0.2", "screenfull": "^6.0.2",
"vue": "^3.3.11", "vue": "^3.3.11",
"vue-router": "4" "vue-router": "4",
"vxe-table": "^4.5.17",
"xe-utils": "^3.5.14"
}, },
"devDependencies": { "devDependencies": {
"@types/lodash-es": "^4.17.12", "@types/lodash-es": "^4.17.12",

25
pnpm-lock.yaml generated
View File

@@ -43,6 +43,12 @@ dependencies:
vue-router: vue-router:
specifier: '4' specifier: '4'
version: 4.2.5(vue@3.3.13) version: 4.2.5(vue@3.3.13)
vxe-table:
specifier: ^4.5.17
version: 4.5.17(vue@3.3.13)(xe-utils@3.5.14)
xe-utils:
specifier: ^3.5.14
version: 3.5.14
devDependencies: devDependencies:
'@types/lodash-es': '@types/lodash-es':
@@ -738,6 +744,10 @@ packages:
engines: {node: '>=0.4.0'} engines: {node: '>=0.4.0'}
dev: false dev: false
/dom-zindex@1.0.1:
resolution: {integrity: sha512-M/MERVDZ8hguvjl6MAlLWSLYLS7PzEyXaTb5gEeJ+SF+e9iUC0sdvlzqe91MMDHBoy+nqw7wKcUOrDSyvMCrRg==}
dev: false
/echarts@5.4.3: /echarts@5.4.3:
resolution: {integrity: sha512-mYKxLxhzy6zyTi/FaEbJMOZU1ULGEQHaeIeuMR5L+JnJTpz+YR03mnnpBhbR4+UYJAgiXgpyTVLffPAjOTLkZA==, tarball: https://registry.npmmirror.com/echarts/-/echarts-5.4.3.tgz} resolution: {integrity: sha512-mYKxLxhzy6zyTi/FaEbJMOZU1ULGEQHaeIeuMR5L+JnJTpz+YR03mnnpBhbR4+UYJAgiXgpyTVLffPAjOTLkZA==, tarball: https://registry.npmmirror.com/echarts/-/echarts-5.4.3.tgz}
dependencies: dependencies:
@@ -1188,6 +1198,21 @@ packages:
'@vue/shared': 3.3.13 '@vue/shared': 3.3.13
typescript: 5.3.3 typescript: 5.3.3
/vxe-table@4.5.17(vue@3.3.13)(xe-utils@3.5.14):
resolution: {integrity: sha512-HcXxI0kMiW90NikPeB/pqkAsm/pQi7OKKBaINojE1pSWWT2MPcs472zVBCEzIqh4aprhhC62lfH6hYzM6c5QWw==}
peerDependencies:
vue: ^3.2.28
xe-utils: ^3.5.0
dependencies:
dom-zindex: 1.0.1
vue: 3.3.13(typescript@5.3.3)
xe-utils: 3.5.14
dev: false
/xe-utils@3.5.14:
resolution: {integrity: sha512-Xq6mS8dWwHBQsQUEBXcZYSaBV0KnNLoVWd0vRRDI3nKpbNxfs/LSCK0W21g1edLFnXYfKqg7hh5dakr3RtYY0A==}
dev: false
/yallist@4.0.0: /yallist@4.0.0:
resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==, tarball: https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz} resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==, tarball: https://registry.npmmirror.com/yallist/-/yallist-4.0.0.tgz}
dev: true dev: true

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@@ -1,7 +1,8 @@
<script lang="ts"> <script lang='ts'>
import { defineComponent, createVNode, reactive } from 'vue' import { defineComponent, createVNode, reactive } from 'vue'
import { ElTableColumn } from 'element-plus' import { Column } from 'vxe-table'
import { uuid } from '@/utils/random' import { uuid } from '@/utils/random'
export default defineComponent({ export default defineComponent({
name: 'Column', name: 'Column',
props: { props: {
@@ -14,7 +15,7 @@ export default defineComponent({
const attr = reactive(props.attr) const attr = reactive(props.attr)
attr['column-key'] = attr['column-key'] ? attr['column-key'] : attr.prop || uuid() attr['column-key'] = attr['column-key'] ? attr['column-key'] : attr.prop || uuid()
return () => { return () => {
return createVNode(ElTableColumn, attr, slots.default) return createVNode(Column, attr, slots.default)
} }
} }
}) })

View File

@@ -1,21 +1,23 @@
<template> <template>
<el-table <vxe-table
ref="tableRef" ref="tableRef"
class="ba-data-table w100" class="ba-data-table w100"
header-cell-class-name="table-header-cell" header-cell-class-name="table-header-cell"
:data="tableStore.table.data" :data="tableStore.table.data"
:row-key="tableStore.pk"
:border="true" :border="true"
v-loading="tableStore.table.loading" v-loading="tableStore.table.loading"
stripe stripe
@selection-change="onSelectionChange" @selection-change="onSelectionChange"
v-bind="$attrs" v-bind="$attrs"
:column-config="{resizable: true}"
:tree-config="{}"
> >
<!-- Column 组件内部是 el-table-column --> <!-- Column 组件内部是 el-table-column -->
<Column <Column
:attr="item" :attr="item"
:key="key + '-column'" :key="key + '-column'"
v-for="(item, key) in tableStore.table.column" v-for="(item, key) in tableStore.table.column"
:tree-node='item.treeNode'
> >
<!-- tableStore 预设的列 render 方案 --> <!-- tableStore 预设的列 render 方案 -->
<template v-if="item.render" #default="scope"> <template v-if="item.render" #default="scope">
@@ -23,20 +25,20 @@
:field="item" :field="item"
:row="scope.row" :row="scope.row"
:column="scope.column" :column="scope.column"
:index="scope.$index" :index="scope.rowIndex"
:key=" :key="
key + key +
'-' + '-' +
scope.$index + scope.rowIndex +
'-' + '-' +
item.render + item.render +
'-' + '-' +
(item.prop ? '-' + item.prop + '-' + scope.row[item.prop] : '') (item.field ? '-' + item.field + '-' + scope.row[item.field] : '')
" "
/> />
</template> </template>
</Column> </Column>
</el-table> </vxe-table>
<div v-if="props.pagination" class="table-pagination"> <div v-if="props.pagination" class="table-pagination">
<el-pagination <el-pagination
:currentPage="tableStore.table.params!.pageNum" :currentPage="tableStore.table.params!.pageNum"

File diff suppressed because one or more lines are too long

View File

@@ -59,6 +59,7 @@ const onMenuCollapse = () => {
color: v-bind('config.getColorVal("headerBarTabActiveColor")'); color: v-bind('config.getColorVal("headerBarTabActiveColor")');
} }
&:hover { &:hover {
color: v-bind('config.getColorVal("headerBarTabActiveColor")');
background-color: v-bind('config.getColorVal("headerBarHoverBackground")'); background-color: v-bind('config.getColorVal("headerBarHoverBackground")');
} }
} }

View File

@@ -165,6 +165,9 @@ const onLogout = () => {}
.nav-menu-item.hover, .nav-menu-item.hover,
.admin-info.hover { .admin-info.hover {
background: v-bind('configStore.getColorVal("headerBarHoverBackground")'); background: v-bind('configStore.getColorVal("headerBarHoverBackground")');
.nav-menu-icon {
color: v-bind('configStore.getColorVal("headerBarTabActiveColor")') !important;
}
} }
} }
.dropdown-menu-box :deep(.el-dropdown-menu__item) { .dropdown-menu-box :deep(.el-dropdown-menu__item) {

View File

@@ -1,8 +1,8 @@
<template> <template>
<component :is="config.layout.layoutMode"></component> <component :is='config.layout.layoutMode'></component>
</template> </template>
<script setup lang="ts"> <script setup lang='ts'>
import { reactive } from 'vue' import { reactive } from 'vue'
import { useConfig } from '@/stores/config' import { useConfig } from '@/stores/config'
import { useNavTabs } from '@/stores/navTabs' import { useNavTabs } from '@/stores/navTabs'
@@ -58,37 +58,22 @@ const init = () => {
title: '控制台', title: '控制台',
name: 'dashboard', name: 'dashboard',
path: 'dashboard', path: 'dashboard',
icon: 'fa fa-dashboard', icon: 'el-icon-Platform',
menu_type: 'tab', menu_type: 'tab',
url: '', url: '',
component: '/src/views/dashboard/index.vue', component: '/src/views/dashboard/index.vue',
keepalive: 'dashboard', keepalive: 'dashboard',
extend: 'none', extend: 'none',
children: [ children: []
{
id: 94,
pid: 1,
type: 'button',
title: '查看',
name: 'dashboard/index',
path: '',
icon: '',
menu_type: null,
url: '',
component: '',
keepalive: 0,
extend: 'none'
}
]
}, },
{ {
id: 3, id: 3,
pid: 0, pid: 0,
type: 'menu', type: 'menu',
title: '测试1', title: '审计管理',
name: 'test', name: 'test',
path: 'test', path: 'test',
icon: 'fa fa-dashboard', icon: 'el-icon-List',
menu_type: 'tab', menu_type: 'tab',
url: '', url: '',
component: '/src/views/dashboard/test.vue', component: '/src/views/dashboard/test.vue',
@@ -102,7 +87,7 @@ const init = () => {
title: '权限管理', title: '权限管理',
name: 'auth', name: 'auth',
path: 'auth', path: 'auth',
icon: 'fa fa-group', icon: 'el-icon-Tools',
menu_type: null, menu_type: null,
url: '', url: '',
component: '', component: '',
@@ -116,7 +101,7 @@ const init = () => {
title: '角色管理', title: '角色管理',
name: 'auth/role', name: 'auth/role',
path: 'auth/role', path: 'auth/role',
icon: 'fa fa-group', icon: 'el-icon-Avatar',
menu_type: 'tab', menu_type: 'tab',
url: '', url: '',
component: '/src/views/auth/role.vue', component: '/src/views/auth/role.vue',
@@ -131,7 +116,7 @@ const init = () => {
title: '菜单规则管理', title: '菜单规则管理',
name: 'auth/menu', name: 'auth/menu',
path: 'auth/menu', path: 'auth/menu',
icon: 'el-icon-Grid', icon: 'el-icon-Menu',
menu_type: 'tab', menu_type: 'tab',
url: '', url: '',
component: '/src/views/auth/menu/index.vue', component: '/src/views/auth/menu/index.vue',

View File

@@ -4,9 +4,7 @@
<router-view v-slot='{ Component }'> <router-view v-slot='{ Component }'>
<transition :name='config.layout.mainAnimation' mode='out-in'> <transition :name='config.layout.mainAnimation' mode='out-in'>
<keep-alive :include='state.keepAliveComponentNameList'> <keep-alive :include='state.keepAliveComponentNameList'>
<div class='default-main'> <component :is='Component' :key='state.componentKey' />
<component :is='Component' :key='state.componentKey' />
</div>
</keep-alive> </keep-alive>
</transition> </transition>
</router-view> </router-view>

View File

@@ -4,6 +4,8 @@ import router from './router'
import pinia from '@/stores/index' import pinia from '@/stores/index'
import { registerIcons } from '@/utils/common' import { registerIcons } from '@/utils/common'
import mitt from 'mitt' import mitt from 'mitt'
import VXETable from 'vxe-table'
import 'vxe-table/lib/style.css'
import ElementPlus from 'element-plus' import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css' import 'element-plus/dist/index.css'
import 'element-plus/theme-chalk/display.css' import 'element-plus/theme-chalk/display.css'
@@ -16,6 +18,7 @@ const app = createApp(App)
app.use(router) app.use(router)
app.use(pinia) app.use(pinia)
app.use(ElementPlus) app.use(ElementPlus)
app.use(VXETable)
registerIcons(app) // icons registerIcons(app) // icons
app.mount('#app') app.mount('#app')

View File

@@ -17,7 +17,7 @@ const loadingInstance: LoadingInstance = {
* 根据运行环境获取基础请求URL * 根据运行环境获取基础请求URL
*/ */
export const getUrl = (): string => { export const getUrl = (): string => {
if (import.meta.env.MODE == 'development') return '/api' if (import.meta.env.MODE == 'development' || location.hostname === 'localhost') return '/api'
return window.location.protocol + '//' + window.location.host return window.location.protocol + '//' + window.location.host
} }

View File

@@ -52,7 +52,9 @@ export default class TableStore {
requestPayload(this.method, this.table.params) requestPayload(this.method, this.table.params)
) )
).then((res: any) => { ).then((res: any) => {
this.table.data = res.data.records || res.data this.table.data = res.data.records || res.data
console.log(this.table.data)
this.table.total = res.data.total || res.data.length this.table.total = res.data.total || res.data.length
this.table.loading = false this.table.loading = false
}) })

View File

@@ -1,38 +1,42 @@
<template> <template>
<TableHeader> <div class='default-main'>
<template v-slot:operation> <TableHeader>
<el-button type='primary' @click='addMenu'>新增</el-button> <template v-slot:operation>
</template> <el-button :icon='Plus' type='primary' @click='addMenu'>添加</el-button>
</TableHeader> </template>
<Table ref='tableRef' :pagination='false' /> </TableHeader>
<popupForm ref='popupRef'></popupForm> <Table ref='tableRef' :pagination='false' />
<popupForm ref='popupRef'></popupForm>
</div>
</template> </template>
<script setup lang='ts'> <script setup lang='ts'>
import { Plus } from '@element-plus/icons-vue'
import { ref, onMounted, provide } from 'vue' import { ref, onMounted, provide } from 'vue'
import TableStore from '@/utils/tableStore' import TableStore from '@/utils/tableStore'
import Table from '@/components/table/index.vue' import Table from '@/components/table/index.vue'
import TableHeader from '@/components/table/header/index.vue' import TableHeader from '@/components/table/header/index.vue'
import popupForm from './popupForm.vue' import popupForm from './popupForm.vue'
import { useNavTabs } from '@/stores/navTabs'
defineOptions({ defineOptions({
name: 'auth/menu' name: 'auth/menu'
}) })
const tableRef = ref() const tableRef = ref()
const popupRef = ref() const popupRef = ref()
const navTabs = useNavTabs()
const tableStore = new TableStore({ const tableStore = new TableStore({
url: '/user-boot/function/functionTree', url: '/user-boot/function/getRouteMenu',
column: [ column: [
{ type: 'selection', align: 'center', width: '60' }, { title: '菜单名称', field: 'title', align: 'left', treeNode: true },
{ label: '菜单名称', prop: 'title', align: 'left' },
{ {
label: '图标', title: '图标',
prop: 'icon', field: 'icon',
align: 'center', align: 'center',
width: '60', width: '60',
render: 'icon' render: 'icon'
}, },
{ {
label: '操作', title: '操作',
align: 'center', align: 'center',
width: '130', width: '130',
render: 'buttons', render: 'buttons',
@@ -54,10 +58,10 @@ const tableStore = new TableStore({
icon: 'el-icon-Delete', icon: 'el-icon-Delete',
render: 'confirmButton', render: 'confirmButton',
popconfirm: { popconfirm: {
confirmButtonText:'确认', confirmButtonText: '确认',
cancelButtonText: '取消', cancelButtonText: '取消',
confirmButtonType: 'danger', confirmButtonType: 'danger',
title: '确定删除该菜单吗?', title: '确定删除该菜单吗?'
}, },
click: (row) => { click: (row) => {
popupRef.value.open('编辑菜单', row) popupRef.value.open('编辑菜单', row)
@@ -71,7 +75,22 @@ provide('tableStore', tableStore)
onMounted(() => { onMounted(() => {
tableStore.table.ref = tableRef.value tableStore.table.ref = tableRef.value
tableStore.index() // tableStore.index()
const handlerRouter = (arr: any[]) => {
return arr.map((item: any, index: number) => {
if (item.children && item.children.length > 0) {
item.children = handlerRouter(item.children)
}
return {
...item,
title: item.meta.title,
icon: item.meta.icon,
id: index
}
})
}
tableStore.table.data = handlerRouter(navTabs.state.tabsViewRoutes)
tableStore.table.loading = false
}) })
const addMenu = () => { const addMenu = () => {
console.log(popupRef) console.log(popupRef)

View File

@@ -1,3 +1,3 @@
<template> <template>
role <div>123</div>
</template> </template>

10
types/table.d.ts vendored
View File

@@ -1,7 +1,7 @@
import Table from '@/components/table/index.vue' import Table from '@/components/table/index.vue'
import { Component } from 'vue' import { Component } from 'vue'
import type { VxeColumnProps } from 'vxe-table'
import type { PopconfirmProps, ButtonType, FormInstance, ButtonProps, TableColumnCtx, ColProps } from 'element-plus' import type { PopconfirmProps, ButtonType, ButtonProps } from 'element-plus'
import { Mutable } from 'element-plus/es/utils' import { Mutable } from 'element-plus/es/utils'
declare global { declare global {
@@ -29,7 +29,7 @@ declare global {
} }
/* 表格列 */ /* 表格列 */
interface TableColumn extends Partial<TableColumnCtx<TableRow>> { interface TableColumn extends VxeColumnProps {
render?: render?:
| 'icon' | 'icon'
| 'switch' | 'switch'
@@ -58,7 +58,7 @@ declare global {
row: TableRow, row: TableRow,
field: TableColumn, field: TableColumn,
value: any, value: any,
column: TableColumnCtx<TableRow>, column: VxeColumnProps,
index: number index: number
) => any ) => any
// 自定义渲染模板方法可返回html内容 // 自定义渲染模板方法可返回html内容
@@ -66,7 +66,7 @@ declare global {
row: TableRow, row: TableRow,
field: TableColumn, field: TableColumn,
value: any, value: any,
column: TableColumnCtx<TableRow>, column: VxeColumnProps,
index: number index: number
) => string ) => string
} }