【代码背景】
【代码实现】
1# -> 代码复用的根底是你须要一个可复用的组件
2# -> 在展现页面应用动静表格组件
3# -> 如何给动静表格依据需要动静增加序号列/索引列
【代码背景】
有这样一个业务需要场景,有大略十几张表归属于某个类别,用户心愿在同一个页面,通过抉择不同的查问指标展现不同的表格,这些表的表头款式相似然而又不完全相同,怎么做呢?
到目前为止所有基于Element UI的表格款式都是间接在页面写死的,像官网这样:
<el-table :data="tableData" style="width: 100%">
<el-table-column prop="date" label="日期" width="180"></el-table-column><el-table-column prop="name" label="姓名" width="180"></el-table-column><el-table-column prop="address" label="地址"></el-table-column>
</el-table>
要解决上述问题,最简略暴力的形式是为每个表写一个独自组件,而后通过select框触发事件切换不同组件路由渲染页面,当然这种形式很笨,也不合乎代码复用的根本准则,所以为了偷懒,为了坚守代码复用的根本准则,开始思考有没有更好的形式来解决这个问题。
仔细观察这个<el-table>,表格数据是通过:data绑定的,表格头部数据则是通过<el-table-column>标签展现的,表头数据是不是也能够通过某种传参的形式联合v-for来渲染<el-table-column>的具体数据呢?在度娘的帮忙下,果然有大佬曾经这样做了,实现了动静表格,参考链接挂在最底下了哦,在此特别感谢收费分享常识的大佬们,常识无价,学无止境。
现将本我的项目的具体实现代码记录如下,欠缺了一些代码的注解,尝试帮忙了解。
【代码实现】
1# -> 代码复用的根底是你须要一个可复用的组件
在/components/Table文件夹下新建两个组件
DynamicTable.vue
<template>
<!-- 动静展现表格 -->
<el-table :data="tableData" border stripe :height="height" @row-click="handleRowClick">
<!-- v-for 循环取表头数据 --><template v-for="item in tableHeader"> <table-column v-if="item.children && item.children.length" :key="item.id" :column-header="item" /> <el-table-column v-else :key="item.id" :label="item.label" :prop="item.prop" align="center" /></template>
</el-table>
</template>
<script>
import TableColumn from '@/components/Table/TableColumn'
export default {
name: 'DynamicTable',components: { TableColumn},props: { // 表格的数据 tableData: { type: Array, required: true }, // 多级表头的数据 tableHeader: { type: Array, required: true }, // 表格的高度 height: { type: String, default: '300' }},methods: { // 行点击事件 handleRowClick (row, column, event) { // console.log(row) // console.log(column) // console.log(event) // 告诉调用父组件的row-click事件 // row作为参数传递过来 this.$emit('row-click', row) }}
}
</script>
TableColumn.vue
<template>
<el-table-column
:label="columnHeader.label":prop="columnHeader.label"align="center"
<!--columnHeader对应:column-header--><template v-for="item in columnHeader.children"> <tableColumn v-if="item.children && item.children.length" :key="item.id" :column-header="item" /> <el-table-column v-else :key="item.name" :label="item.label" :prop="item.prop" align="center" /></template>
</el-table-column>
</template>
<script>
export default {
name: 'TableColumn',props: { columnHeader: { type: Object, required: true }}
}
</script>
<style scoped>
</style>
几点重要阐明:
(1)表格头部的传参次要分为两类:带children节点和不带children节点的,如下图所示
Element实现动静表格的示例代码
请留神children节点是为了实现简单表头的渲染,例如下面这个示例最终的表头渲染款式如下:
Element实现动静表格的示例代码
那么问题来了,<el-table-column>是<el-table>的标签,那这个<table-column>是个啥?
(2)DynamicTable.vue调用TableColumn.vue组件
Element实现动静表格的示例代码
DynamicTable.vue通过:column-header给TableColumn.vue传递带children子节点的表头信息,TableColumn.vue接管到这个节点信息后,次要做了以下两件事件:
第一:通过<el-table-column>渲染了一个label标签
第二:持续判断该节点是否存在children子节点
=> 如果存在children节点,持续通过<table-column>进行渲染,持续把这个子节点传给TableColumn.vue组件,反复上述步骤
=> 如果不存在children节点,示意这是一个终止节点,通过<el-table-column>渲染完结
2# -> 在展现页面应用动静表格组件
<template>
<div class="demo">
<el-card> <!--查问区域--> <el-row :gutter="10"> <el-col :span="6"> <div class="grid-content bg-purple"> <span style="margin-right: 10px">抉择框 -</span> <el-select v-model="specified_table" placeholder="请抉择" > <el-option v-for="item in options" :key="item.zb_code" :label="item.zb_name" :value="item.zb_code" /> </el-select> </div> </el-col> <el-col :span="6"> <div class="grid-content bg-purple"> <el-button type="primary" plain @click="handleQueryClick">查 询</el-button> </div> </el-col> </el-row> <!--表格区域--> <dynamic-table v-if="dynamicTableShow" :table-data="tableData" :table-header="tableHeaders" :height="'550px'" /></el-card>
</div>
</template>
<script>
// 引入组件
import DynamicTable from '@/components/Table/DynamicTable'
// 获取表头信息
import { getTableHeader02_1, getTableHeader02_2, getTableHeader02_3, getTableHeader02_4 } from '@/api/table-header'
export default {
name: 'Index',components: { // 组件注册 DynamicTable},data () { return { // -- 查问 ---------------------- options: [ // { zb_name: '指标名', zb_code: '指标代码' } ], specified_table: '', // 指标值 // -- 表格 ---------------------- dynamicTableShow: true, // DynamicTable组件从新渲染变量 // 表头数据 tableHeaders: [], // 表格数据 tableData: [] }},created () { // api-获取指标的下拉框数据 getSpecifiedTable().then(res => { this.options = res.data })},methods: { // 判断值是否在数组中 isExistArr (arr, val) { return arr.includes(val) }, // 从新渲染表格 refreshTable (zb_code) { // 依据value值获取label值 const obj = this.options.find((item) => { return item.zb_code === zb_code }) console.log(zb_code) console.log(obj.zb_name) // 设置dynamicTableShow为false,使得DynamicTable组件从新渲染 this.dynamicTableShow = false // 依据不同指标渲染不同的表头 const TBArr01 = ['M01', 'M02', 'M03', 'M05'] // 第1类表 const TBArr02 = ['M04', 'M07', 'M08', 'M12'] // 第2类表 const TBArr03 = ['M09', 'M10', 'M11'] // 第3类表 const TBArr04 = ['M06'] // 第4类表 if (this.isExistArr(TBArr01, zb_code)) { this.tableHeaders = getTableHeader02_1(obj.zb_name) // 渲染表头款式1 }
if (this.isExistArr(TBArr02, zb_code)) {
this.tableHeaders = getTableHeader02_2(obj.zb_name) // 渲染表头款式2 }
if (this.isExistArr(TBArr03, zb_code)) {
this.tableHeaders = getTableHeader02_3(obj.zb_name) // 渲染表头款式3
if (this.isExistArr(TBArr04, zb_code)) {
this.tableHeaders = getTableHeader02_4(obj.zb_name) // 渲染表头款式4 // api - 获取表格数据
getTableList02(zb_code).then(res => {
this.tableData = res.data }) // 此处是DOM还没有更新,此处的代码是必须的 this.$nextTick(() => { // DOM当初更新了