【Vue】el-table 简易表格可筛选列
需求实现:
代码逻辑:
按钮控件:
<el-popover placement="top-start"> <el-checkbox-group v-model="checkedColumns" @change="whenColumnBoxChange"> <div v-for="(col, idx) in optionColumns" :key="`optionColumns${idx}`"> <el-checkbox :label="col.property">{{ col.label }}</el-checkbox> </div> </el-checkbox-group> <el-button style="float: right;" slot="reference" type="primary" size="mini">列筛选</el-button> </el-popover>
表格组件要追加Ref标记:
<el-table ref="elTable" v-loading="loading" size="small" stripe :height="tableHeight" :data="tableData">
需要设置的数据对象:
defaultShow: true, checkedColumns: [], optionColumns: []
所需方法:
// 当选择时重新渲染表格 whenColumnBoxChange() { this.$refs['elTable'].doLayout() }, // 判断该列是否展示 getColumnShowFlag(colIdent) { return this.defaultShow || this.checkedColumns.includes(colIdent) }, // 初始化筛选项,并保证默认正常展示 (created调用) initialOptionColumnsData() { this.$nextTick(() => { const { columns } = this.$refs['elTable'] this.optionColumns = columns.filter(x => x.property).map(x => { return { id: x.id, label: x.label, property: x.property, flag: true } }) this.checkedColumns = this.optionColumns.map(x => x.property) this.defaultShow = false }) },
需要对一个个列进行判断方法设置:
<el-table-column v-if="getColumnShowFlag('apInAmount')" prop="apInAmount" min-width="120px" label="收入总额(元)" align="right" show-overflow-tooltip> <template slot-scope="{ row }"> {{ transFormAmount(row.apInAmount) }} </template> </el-table-column>
更新补充
一、追加默认过滤的列:
初始化方法追加一个用来过滤的集合:
// 初始化筛选项,并保证默认正常展示 initialOptionColumnsData() { this.$nextTick(() => { const elTable = this.$refs['elTable'] this.optionColumns = elTable.columns.filter(x => x.property).map(x => { return { id: x.id, label: x.label, property: x.property, flag: true } }) this.checkedColumns = this.optionColumns.map(x => x.property).filter(x => !this.excludeColumns.includes(x)) this.defaultShow = false elTable.doLayout() }) },
在需要过滤的集合中设置字段property即可:
excludeColumns: [ 'servCode', 'deName', 'inPmanagerName', 'inBegTime', 'inEndTime' ]
二、自定义列内容污染问题:
发现现有BUG,如果是扩展template自定义列内容时会污染下一列,解决办法就是对template也进行判断
<el-table-column v-if="getColumnShowFlag('apInAmount')" prop="apInAmount" min-width="120px" label="收入总额(元)" align="right" show-overflow-tooltip> <template v-if="getColumnShowFlag('apInAmount')" slot-scope="{ row }"> {{ transFormAmount(row.apInAmount) }} </template> </el-table-column>
三、操作样式追补:
利用操作列固定头来设置,将按钮改为图标:
<el-table-column fixed="right" label="操作" width="180px" align="center"> <template slot="header"> <el-popover placement="top-start" trigger="hover"> <el-checkbox-group v-model="checkedColumns" @change="whenColumnBoxChange"> <div v-for="(col, idx) in optionColumns" :key="`optionColumns${idx}`"> <el-checkbox :label="col.property">{{ col.label }}</el-checkbox> </div> </el-checkbox-group> <span slot="reference"> 操作 <i class="el-icon-s-tools" style="margin-left: 5px;" /> </span> </el-popover> </template> <template slot-scope="scope"> <span v-permission="permits.update" class="link-color" @click="openEditDialog(scope.row)"> <i class="el-icon-edit-outline" /> 设置 </span> <span v-permission="permits.update" class="link-color" @click="openItemDialog(scope.row)"> <i class="el-icon-edit-outline" /> 计划 </span> </template> </el-table-column>
四、header插槽不更新复选框问题
el-table 后续使用嵌套组件加载时发现复选框不更新:
原因找到了:
https://blog.csdn.net/yy_demo/article/details/139067420
解决办法:
<template slot="header"> 改为 <template #header> 检测数据更新刷新组件
五、发现存在nextTick报错:
初始化的列看不到值了
解决办法是对列增加key属性,标识唯一
https://www.jianshu.com/p/98f329c4a582
但是随后第二个功能的表格又不起作用了,排查了一下午问题才发现v-permission影响的
就是操作列中的操作标签使用了v-permission进行权限控制,但是在改用v-if后就不会报错了
为了优化使用方法,我追加了全局注册的方法
import Vue from 'vue' import store from '@/store' /** * 权限校验 */ Vue.prototype.$permitValidate = val => { return store.getters.permissions.includes(val) }