出现场景
在使用 Element Plus 做后台管理系统的时候,Table 表格组件往往是使用最频繁的,所以打算将表格封装一下,各个页面在使用的时候,只需要关心表格列 columns 和数据 data 即可。
封装时要考虑的问题:
- table组件自带的属性可以直接使用
- 在列中展示按钮、标签等信息时,使用 render 函数渲染页面元素
git地址
完整代码git地址:
- github: github.com/zzxprint/el…
- gitee: gitee.com/zzxprint/el…
掘金有一位大佬已有封装好的更完善的表格组件 ProTable,戳这里查看
封装组件
创建一个组件,接收列信息 columns 和数据 data ,循环读取其中的列头信息和取值信息,如果读取到属性有 render ,则显示其返回的 VNode 内容。
<!-- components/SimpleTable.vue -->
<template>
<el-table
style="width: 100%"
v-bind="$attrs"
:data="data"
>
<template v-for="column in props.columns" :key="column">
<RenderTableColumn v-bind="column" />
</template>
</el-table>
</template>
<script lang="tsx" setup name="SimpleTable">
const props = defineProps({
data: Array<any>,
columns: Array<any>
})
const RenderTableColumn = (column: any) => {
return (
<el-table-column>
{{
default: (scope: any) => {
if (column.render) return column.render(scope)
return scope.row[column.prop]
},
header: () => {
if (column.headerRender) return column.headerRender(column)
return column.label
}
}}
</el-table-column>
)
}
</script>
上面代码中, render 函数使用了 jsx/tsx 语法,因此需要先安装一下依赖,执行:
- npm i @vitejs/plugin-vue-jsx -D
我这里使用的是 vite ,所以在 vite.config.ts 文件中加上:
//...
import vueJsx from '@vitejs/plugin-vue-jsx'
export default defineConfig({
plugins: [
vue(),
vueJsx(),
// ...
],
})
在其他页面使用
<!-- App.vue -->
<template>
<SimpleTable :columns="columns" :data="tableData" />
</template>
<script setup lang="tsx">
import SimpleTable from './components/SimpleTable.vue'
const columns = [
{
label: 'Date',
prop: 'date',
render: (scope: any) => {
return (
<div style="display: flex; align-items: center">
<el-icon><timer /></el-icon>
<span style="margin-left: 10px">{ scope.row.date }</span>
</div>
)
}
},
{
label: 'Name',
prop: 'name',
render: (scope: any) => {
return (
<el-tag>{ scope.row.name }</el-tag>
)
}
},
{
label: 'Add.',
prop: 'address'
},
{
label: 'Operations',
prop: '',
render: () => {
return (
<div>
<el-button size="small">Edit</el-button>
<el-button size="small" type="danger">Delete</el-button>
</div>
)
}
},
]
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
}
]
</script>
在渲染列信息时,上述示例中使用 el-icon 时会发现其无法渲染,我们需要将所有的 icon 统一在 main.ts 中引入,注册成独立的组件,这样就可以在正常渲染了。
// main.ts
import { createApp } from 'vue'
import * as Icons from "@element-plus/icons-vue"
import App from './App.vue'
const app = createApp(App)
Object.keys(Icons).forEach(key => {
app.component(key, Icons[key as keyof typeof Icons])
})
app.mount('#app')