Vue+ElementUI 实现 动态调整表格列 显示隐藏&显示顺序
先来看一个需求
1.表格可多选 2.表格可排序 3.表格可拖动列宽 4.表格固定列和表头 5.表格列顺序可调整 6.表格列可隐藏或显示 7.表格设置需要实时保存 复制代码
解决思路
其中[1、2、3、4 ] Element-UI table
组件原生就支持的
[5] 列顺序可调整 可以通过 改变 el-table-column
的渲染顺序实现
[6] 可以通过控制 el-table-column
的展示与隐藏实现
[7] 将每次修改存至本地localStorage
Table组件 地址:element.eleme.io/#/zh-CN/com…
上代码:
核心在于需要循环渲染 el-table-column
<template>部分
<!--列设置按钮--> <el-dropdown trigger="click"> <el-button icon="el-icon-s-operation" size="mini">列设置</el-button> <el-dropdown-menu slot="dropdown"> <span class="title">列设置</span> <el-tree draggable :data="columns" :props="defaultProps" :allow-drop="allowDrop" @node-drop="handleDrop"> <span class="tree-table-setting" slot-scope="{ node, data }"> <el-switch @change="saveTableColumns" v-model="data.show"> </el-switch> <span>{{ node.label }}</span> </span> </el-tree> </el-dropdown-menu> </el-dropdown> <!--表格--> <div> <el-table :key="tableKey" :data="tableData" :height="tableHeight" :row-style="{ height: '40px' }" :cell-style="{ borderRight: 'none' }" :header-cell-style="{ height: '40px', padding: 0, background: '#f6f8fa', color: '#333' }" @row-click="handelTableClick" @selection-change="handleSelectionChange" @header-dragend="surverWidth" border size="mini" tooltip-effect="dark" highlight-current-row > <el-table-column align="center" type="selection"> </el-table-column> <template v-for="item in columns"> <el-table-column v-if="item.show" show-overflow-tooltip :prop="item.prop" :sortable="item.sortable" :label="item.label" :width="item.width" :key="item.prop" :resizable="item.resizable" > <template slot-scope="scope"> <span v-if="item.prop === 'clue_type'">{{ scope.row[item.prop] | clueType }}</span> <span v-else-if="item.prop === 'clue_source'">{{ scope.row[item.prop] | clueSource }}</span> <span v-else-if="item.prop === 'contact_type'">{{ scope.row[item.prop] | commonType }}</span> <span v-else-if="item.prop === 'company_name'" class="link">{{ scope.row[item.prop] }}</span> <span v-else>{{ scope.row[item.prop] }}</span> </template> </el-table-column> </template> <!-- 固定列 --> <el-table-column fixed="right" label="关注" width="56"> <template slot-scope="scope"> <el-button style="height: 10px;padding:0; margin:0;" type="text" @click.native.stop="clueTableRowClick(scope.row, 'collect')" size="mini" > <img v-if="scope.row.collect === 1" style="width:16px" src="@/assets/star1.png" /> <img v-else style="width:16px" src="@/assets/star0.png" /> </el-button> </template> </el-table-column> <el-table-column fixed="right" label="编辑" width="56"> <template slot-scope="scope"> <el-button style="height: 10px;padding:0; margin:0;" type="text" @click.native.stop="clueTableRowClick(scope.row, 'edit')" size="mini" > <img style="width:16px" src="@/assets/edit.png" /> </el-button> </template> </el-table-column> <el-table-column> </el-table-column> </el-table> </div> 复制代码
注意事项
1.控制el-table-column显示与隐藏使用v-show无效,需要使用v-if。
2.部分列需要使用过滤器 我这里使用了if做判断。
3.由于虚拟Dom算法导致有时表格并不会实时刷新,这里需要给table添加key值。
4.列设置中可上下拖动采用 Tree组件。
5.由于需要固定列和表头 每次获取到表格数据后,再给tableHight赋值。
const winHeight = document.body.clientHeight // 窗口大小 - 表格顶部高度 this.tableHeight = winHeight - 260 复制代码
6.这里由于给row绑定了click事件,需要给row中的Button按钮添加.native
修饰,防止事件冒泡添加.stop
修饰。
<script>部分
export default { data() { // 表格key tableKey: 1, // 表格数据 tableData: [], // 默认表格高度 tableHeight:600, // 表格展示项配置 columns:[ { prop: 'name', // 对应列内容的字段名 label: '姓名', // 显示的标题 width: 66, // 对应列的宽度 resizable: true, // 对应列是否可以通过拖动改变宽度(需要在 el-table 上设置 border 属性为真) show: true, // 展示与隐藏 sortable: false // 对应列是否可以排序 }, { prop: 'clue_type', label: '线索类型', width: 78, resizable: true, show: true, sortable: false }, // ... 省略部分字段 ], // 列设置中 tree配置 defaultProps: { children: 'children', label: 'label' } }, mounted(){ this.init() }, methods: { init() { // 判断本地是否有表格配置数据 ? 加载 : 忽略 // 获取表格数据 // 重设表格高度 }, allowDrop(draggingNode, dropNode, type) { // 仅允许Tree节点上下拖动 return type !== 'inner' }, // Tree 拖动时更新表格 handleDrop() { this.tableKey++ // 保存表格配置 this.saveTableColumns() }, // 重置表格列设置 resetTable() { // ... 忽略 }, // 显示隐藏切换 && 保存表格配置 saveTableColumns() { // setStorage 封装了 localStorage setStorage('clueTable', this.columns) }, // 选中表格行 handelTableClick(row) { // ... 省略业务逻辑 }, // table多选操作 handleSelectionChange(val) { // ... 省略业务逻辑 }, // 表头拖动事件 surverWidth(newWidth, oldWidth, column, event) { this.columns = this.columns.map(v => { if (v.prop === column.property) v.width = newWidth return v }) this.saveTableColumns() }, // 关注与编辑操作 clueTableRowClick(val, type) { // ... 省略业务逻辑 } } } 复制代码
以上就是该需求的简单实现。
作者:乌龙茶不甜
链接:https://juejin.cn/post/7022140926906597384