Skip to content

Commit 5832fd6

Browse files
author
puhui999
committed
【代码优化】系统菜单管理使用虚拟列表优化加载速度
1 parent c50f59d commit 5832fd6

File tree

1 file changed

+144
-66
lines changed

1 file changed

+144
-66
lines changed

src/views/system/menu/index.vue

Lines changed: 144 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -67,87 +67,159 @@
6767

6868
<!-- 列表 -->
6969
<ContentWrap>
70-
<el-table
71-
v-if="refreshTable"
72-
v-loading="loading"
73-
:data="list"
74-
:default-expand-all="isExpandAll"
75-
row-key="id"
76-
>
77-
<el-table-column :show-overflow-tooltip="true" label="菜单名称" prop="name" width="250" />
78-
<el-table-column align="center" label="图标" prop="icon" width="100">
79-
<template #default="scope">
80-
<Icon :icon="scope.row.icon" />
81-
</template>
82-
</el-table-column>
83-
<el-table-column label="排序" prop="sort" width="60" />
84-
<el-table-column :show-overflow-tooltip="true" label="权限标识" prop="permission" />
85-
<el-table-column :show-overflow-tooltip="true" label="组件路径" prop="component" />
86-
<el-table-column :show-overflow-tooltip="true" label="组件名称" prop="componentName" />
87-
<el-table-column label="状态" prop="status">
88-
<template #default="scope">
89-
<el-switch
90-
class="ml-4px"
91-
v-model="scope.row.status"
92-
v-hasPermi="['system:menu:update']"
93-
:active-value="CommonStatusEnum.ENABLE"
94-
:inactive-value="CommonStatusEnum.DISABLE"
95-
:loading="menuStatusUpdating[scope.row.id]"
96-
@change="(val) => handleStatusChanged(scope.row, val as number)"
97-
/>
98-
</template>
99-
</el-table-column>
100-
<el-table-column align="center" label="操作">
101-
<template #default="scope">
102-
<el-button
103-
v-hasPermi="['system:menu:update']"
104-
link
105-
type="primary"
106-
@click="openForm('update', scope.row.id)"
107-
>
108-
修改
109-
</el-button>
110-
<el-button
111-
v-hasPermi="['system:menu:create']"
112-
link
113-
type="primary"
114-
@click="openForm('create', undefined, scope.row.id)"
115-
>
116-
新增
117-
</el-button>
118-
<el-button
119-
v-hasPermi="['system:menu:delete']"
120-
link
121-
type="danger"
122-
@click="handleDelete(scope.row.id)"
123-
>
124-
删除
125-
</el-button>
126-
</template>
127-
</el-table-column>
128-
</el-table>
70+
<el-auto-resizer>
71+
<template #default="{ width }">
72+
<el-table-v2
73+
v-model:expanded-row-keys="expandedRowKeys"
74+
:columns="columns"
75+
:data="list"
76+
:expand-column-key="columns[0].key"
77+
:height="1000"
78+
:width="width"
79+
fixed
80+
row-key="id"
81+
/>
82+
</template>
83+
</el-auto-resizer>
12984
</ContentWrap>
13085

13186
<!-- 表单弹窗:添加/修改 -->
13287
<MenuForm ref="formRef" @success="getList" />
13388
</template>
134-
<script lang="ts" setup>
89+
<script lang="tsx" setup>
13590
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
13691
import { handleTree } from '@/utils/tree'
13792
import * as MenuApi from '@/api/system/menu'
13893
import { MenuVO } from '@/api/system/menu'
13994
import MenuForm from './MenuForm.vue'
140-
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
95+
import DictTag from '@/components/DictTag/src/DictTag.vue'
96+
import { Icon } from '@/components/Icon'
97+
import { ElButton, TableV2FixedDir } from 'element-plus'
98+
import { checkPermi } from '@/utils/permission'
14199
import { CommonStatusEnum } from '@/utils/constants'
100+
import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
142101
143102
defineOptions({ name: 'SystemMenu' })
144103
104+
// 虚拟列表表格
105+
const columns = [
106+
{
107+
key: 'name',
108+
title: '菜单名称',
109+
dataKey: 'name',
110+
width: 250,
111+
fixed: TableV2FixedDir.LEFT
112+
},
113+
{
114+
key: 'icon',
115+
title: '图标',
116+
dataKey: 'icon',
117+
width: 100,
118+
align: 'center',
119+
cellRenderer: ({ cellData: icon }) => <Icon icon={icon} />
120+
},
121+
{
122+
key: 'sort',
123+
title: '排序',
124+
dataKey: 'sort',
125+
width: 60
126+
},
127+
{
128+
key: 'permission',
129+
title: '权限标识',
130+
dataKey: 'permission',
131+
width: 300
132+
},
133+
{
134+
key: 'component',
135+
title: '组件路径',
136+
dataKey: 'component',
137+
width: 500
138+
},
139+
{
140+
key: 'componentName',
141+
title: '组件名称',
142+
dataKey: 'componentName',
143+
width: 200
144+
},
145+
{
146+
key: 'status',
147+
title: '状态',
148+
dataKey: 'status',
149+
width: 60,
150+
fixed: TableV2FixedDir.RIGHT,
151+
cellRenderer: ({ rowData }) => {
152+
// 检查权限
153+
if (!checkPermi(['system:menu:update'])) {
154+
return <DictTag type={DICT_TYPE.COMMON_STATUS} value={rowData.status} />
155+
}
156+
157+
// 如果有权限,渲染 ElSwitch
158+
return (
159+
<ElSwitch
160+
v-model={rowData.status}
161+
active-value={CommonStatusEnum.ENABLE}
162+
inactive-value={CommonStatusEnum.DISABLE}
163+
loading={menuStatusUpdating[rowData.id]}
164+
class="ml-4px"
165+
onChange={(val) => handleStatusChanged(rowData, val)}
166+
/>
167+
)
168+
}
169+
},
170+
{
171+
key: 'operations',
172+
title: '操作',
173+
align: 'center',
174+
width: 160,
175+
fixed: TableV2FixedDir.RIGHT,
176+
cellRenderer: ({ rowData }) => {
177+
// 定义按钮列表
178+
const buttons = []
179+
180+
// 检查权限并添加按钮
181+
if (checkPermi(['system:menu:update'])) {
182+
buttons.push(
183+
<ElButton key="edit" link type="primary" onClick={() => openForm('update', rowData.id)}>
184+
修改
185+
</ElButton>
186+
)
187+
}
188+
if (checkPermi(['system:menu:create'])) {
189+
buttons.push(
190+
<ElButton
191+
key="create"
192+
link
193+
type="primary"
194+
onClick={() => openForm('create', undefined, rowData.id)}
195+
>
196+
新增
197+
</ElButton>
198+
)
199+
}
200+
if (checkPermi(['system:menu:delete'])) {
201+
buttons.push(
202+
<ElButton key="delete" link type="danger" onClick={() => handleDelete(rowData.id)}>
203+
删除
204+
</ElButton>
205+
)
206+
}
207+
// 如果没有权限,返回 null
208+
if (buttons.length === 0) {
209+
return null
210+
}
211+
// 渲染按钮列表
212+
return <>{buttons}</>
213+
}
214+
}
215+
]
216+
145217
const { wsCache } = useCache()
146218
const { t } = useI18n() // 国际化
147219
const message = useMessage() // 消息弹窗
148220
149221
const loading = ref(true) // 列表的加载中
150-
const list = ref<any>([]) // 列表的数据
222+
const list = ref<any[]>([]) // 列表的数据
151223
const queryParams = reactive({
152224
name: undefined,
153225
status: undefined
@@ -156,6 +228,9 @@ const queryFormRef = ref() // 搜索的表单
156228
const isExpandAll = ref(false) // 是否展开,默认全部折叠
157229
const refreshTable = ref(true) // 重新渲染表格状态
158230
231+
// 添加展开行控制
232+
const expandedRowKeys = ref<number[]>([])
233+
159234
/** 查询列表 */
160235
const getList = async () => {
161236
loading.value = true
@@ -186,11 +261,14 @@ const openForm = (type: string, id?: number, parentId?: number) => {
186261
187262
/** 展开/折叠操作 */
188263
const toggleExpandAll = () => {
189-
refreshTable.value = false
264+
if (!isExpandAll.value) {
265+
// 展开所有
266+
expandedRowKeys.value = list.value.map((item) => item.id)
267+
} else {
268+
// 折叠所有
269+
expandedRowKeys.value = []
270+
}
190271
isExpandAll.value = !isExpandAll.value
191-
nextTick(() => {
192-
refreshTable.value = true
193-
})
194272
}
195273
196274
/** 刷新菜单缓存按钮操作 */

0 commit comments

Comments
 (0)