客户需求: 实现动态Table,Table表头定制化展示。
实现思路: 参考Element-UI官方Table表格的写法,对Table进行二次封装。全局使用该组件,方便后期维护。
父组件list.vue:
<div class="text-right mt-5">
<el-button type="info" icon="el-icon-s-operation" @click="openCustom">列表定制el-button>
<TagColumn :popover-visible.sync="popoverVisible" :columns="columns" @success="updateColumns" />
div>
<TagTable
ref="tagTable"
:key="key"
v-loading="PocManager.queryPocTestApplys.loading"
:highlight-current-row="true"
height="calc(100vh - 240px)"
stripe
class="mt-5"
:data-list="gridList"
:columns="columns"
@sort-change="sortChange"
@selection-change="selectionChange"
>
<el-table-column slot="before" type="index" label="序号" />
<el-table-column slot="after" label="操作" width="120px">
<template slot-scope="scope">
<el-button type="text" icon="el-icon-edit" @click="openEdit(scope.row)">编辑el-button>
<el-button type="text" @click="remove(scope.row)">删除el-button>
template>
el-table-column>
TagTable>
openCustom() {
this.popoverVisible = true
},
updateColumns(data) {
this.columns = data
this.popoverVisible = false
this.key = this.key + 1
}
1).子组件tag-table.vue:
<template>
<div>
<el-table :data="dataList" v-bind="$attrs" v-on="$listeners">
<slot name="before" />
<template v-for="column in columns">
<el-table-column v-if="column.status!=='1'" :key="column.code" :label="column.text" :width="column.width" sortable="custom" :prop="column.code">
<template slot-scope="scope">
{{ scope.row[column.code] }}
template>
el-table-column>
template>
<slot name="after" />
<slot />
el-table>
div>
template>
<script>
export default {
props: {
// 表格数据list
dataList: {
default: null,
type: Object,
},
// 表格列
columns: {
default: null,
type: Object,
},
},
data() {
return {
}
},
mounted() {
},
methods: {
},
}
script>
2).子组件tag-column.vue
<template>
<div class="column-popover">
<el-popover
v-model="popoverVisible"
placement="top"
width="160"
>
<el-checkbox-group v-model="checkedColumns">
<el-checkbox v-for="column in columns" :key="column.code" :label="column.code">{{ column.text }}el-checkbox>
el-checkbox-group>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="cancel">取消el-button>
<el-button type="primary" size="mini" @click="submit">确定el-button>
div>
el-popover>
div>
template>
<script>
export default {
props: {
// 列表定制是否显示
popoverVisible: {
type: Boolean,
default: false,
},
// 所有的表格列
columns: {
default: null,
type: Object,
},
},
data() {
return {
checkedColumns: [], // 选中的表格列
columnsOptions: [], // 所有列的code
}
},
computed: {
},
watch: {
columns() {
if (this.columns) {
this.columns.forEach(item => {
this.columnsOptions.push(item.code)
if (item.status !== '1') this.checkedColumns.push(item.code)
})
}
// console.log('columns()', this.columns, this.checkedColumns, this.columnsOptions)
}
},
methods: {
cancel() {
this.$emit('update:popoverVisible', false)
},
submit() {
this.columns.map(item => {
if (this.checkedColumns.includes(item.code)) item.status = '0' // 显示
else item.status = '1' // 隐藏
})
// console.log(this.checkedColumns, this.columns)
// this.$emit('update:popoverVisible', false)
this.$emit('success', this.columns)
}
},
}
script>
<style lang="scss" scoped>
.column-popover{
position: absolute;
min-width: 150px;
right: 20px;
}
style>
组件内引入
1).批量导出component/index.js
import TagTable from './table/tag-table'
import TagColumn from './column/tag-column'
export {
TagTable,
TagColumn
}
2).父组件list.vue
import { TagTable, TagColumn } from '../component'
export default {
components: { TagTable, TagColumn },
}
全局引入
import TagTable from './table/tag-table'
Vue.component('TagTable', TagTable)
import TagColumn from './table/tag-table'
Vue.component('TagColumn', TagColumn)
解决方案
1.Table设置key
:key="key"
2.或问题2的方案可以解决
在子组件tag-table中为了循环,刚开始在 table 里面放置了 div 标签 错误示例: 1.使用 template 标签,template 标签不会被渲染出来,而内部则可以渲染出来。 最终代码如下: 好记性不如烂笔头 1.Element-UI,Table表格
<div v-for="column in columns" :key="column.code">
<el-table-column v-if="column.status!=='1'" :label="column.text" :width="column.width" sortable="custom" :prop="column.code">
<template slot-scope="scope">
{{ scope.row[column.code] }}
template>
el-table-column>
div>
2.将 key 值进行下放,在 template 中是不允许使用 key 值(因为没有意义,template不是一个真实的标签)。 <template v-for="column in columns">
<el-table-column v-if="column.status!=='1'" :key="column.code" :label="column.text" :width="column.width" sortable="custom" :prop="column.code">
<template slot-scope="scope">
{{ scope.row[column.code] }}
template>
el-table-column>
template>
总结
参考文档
2.vue-element-admin,动态Table