1.实现目标
如上,以上效果的难点是“在表格里面实现树形结构”。可以用element-plus框架中的table作为辅助:
可以自己查看文档了解怎么使用。
2.实现思路
上面的效果不难实现,无非就是搭建界面。这里我不用常规方法“一个一个页面搭建”,而是用之前写的文章https://blog.youkuaiyun.com/fageaaa/article/details/145572470中的方法--------通过配置生成页面。
3.实现步骤
3.1新建config配置文件
在menu文件夹下新建config配置文件:
menu/config/content.config.ts:
const contentConfig = {
pageName: 'menu',
header: {
title: '菜单列表',
btnTitle: '新建菜单'
},
propsList: [
{ label: '菜单名称', prop: 'name', width: '180px' },
{ label: '级别', prop: 'type', width: '120px' },
{ label: '菜单url', prop: 'url', width: '150px' },
{ label: '菜单icon', prop: 'icon', width: '200px' },
{ label: '排序', prop: 'sort', width: '120px' },
{ label: '权限', prop: 'permission', width: '150px' },
{ type: 'timer', label: '创建时间', prop: 'createAt' },
{ type: 'timer', label: '更新时间', prop: 'updateAt' },
{ type: 'handler', label: '操作', width: '150px' }
],
childrenTree: {
rowKey: 'id',
treeProps: {
children: 'children'
}
}
}
export default contentConfig
3.2封装组件
将各种各样的表格所在的内容区域封装为一个组件:
components/page-content/page-content.vue:
<template>
<div class="content">
<div class="header">
<h3 class="title">{{ contentConfig?.header?.title ?? '数据列表' }}</h3>
<el-button type="primary" @click="handleNewUserClick">
{{ contentConfig?.header?.btnTitle ?? '新建数据' }}
</el-button>
</div>
<div class="table">
<el-table
:data="pageList"
border
style="width: 100%"
v-bind="contentConfig.childrenTree"
>
<template v-for="item in contentConfig.propsList" :key="item.prop">
<template v-if="item.type === 'timer'">
<el-table-column align="center" v-bind="item">
<template #default="scope">
{{ formatUTC(scope.row[item.prop]) }}
</template>
</el-table-column>
</template>
<template v-else-if="item.type === 'handler'">
<el-table-column align="center" v-bind="item">
<template #default="scope">
<el-button
size="small"
icon="Edit"
type="primary"
text
@click="handleEditBtnClick(scope.row)"
>
编辑
</el-button>
<el-button
size="small"
icon="Delete"
type="danger"
text
@click="handleDeleteBtnClick(scope.row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</template>
<template v-else-if="item.type === 'custom'">
<el-table-column align="center" v-bind="item">
<template #default="scope">
<slot
:name="item.slotName"
v-bind="scope"
:prop="item.prop"
hName="why"
></slot>
</template>
</el-table-column>
</template>
<template v-else>
<el-table-column align="center" v-bind="item" />
</template>
</template>
</el-table>
</div>
<div class="pagination">
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[10, 20, 30]"
layout="total, sizes, prev, pager, next, jumper"
:total="pageTotalCount"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</template>
<script setup lang="ts">
...
interface IProps {
contentConfig: {
pageName: string
header?: {
title?: string
btnTitle?: string
}
propsList: any[]
childrenTree?: any
}
}
const props = defineProps<IProps>()
...
</script>
<style lang="less" scoped>
...
</style>
3.3使用组件
<template>
<div class="menu">
<page-content :content-config="contentConfig" />
</div>
</template>
<script setup lang="ts" name="menu">
import PageContent from '@/components/page-content/page-content.vue'
import contentConfig from './config/content.config'
</script>
<style scoped>
...
</style>