功能点
1、表格是没有分页的
2、点击编辑能定位到对应的位置,进行编辑功能
3、表格滚动时候,编辑弹层需要关闭
效果
代码实现
<template> <el-table ref="multipleTable" > <el-table-column label="操作" width="90"> <template slot-scope="scope"> <el-button type="text" @click="handleClickEdit(scope.row, $event)">编辑</el-button> </template> </el-table-column> </el-table> <!-- 编辑模板 --> <el-popover ref="editPopover" placement="bottom-end" width="370" v-model="visibleEdit" :reference="prevTarget" :key="popperFlag" ></el-popover> </template> <script> // 节流-防抖 import { throttle } from 'throttle-debounce'; export default { data() { return { visibleEdit: false, prevTarget: null, // 编辑 Popover 的 Reference (参照),用于 popover.js 对齐两个元素 popperFlag: false, // 用于编辑 Popover 的刷新 }; }, watch: { value(n) { if(n) { this.$nextTick(() => { // 添加这个用于处理fixed定位导致的列表行错位 console.log('this.$refs.multipleTable--->', this.$refs.multipleTable); this.$refs.multipleTable.doLayout(); }); // 监听滚动,用于编辑框的滚动移除 this.removeEditPopoverListener(n); } } }, methods: { // 监听滚动,用于编辑框的滚动移除 removeEditPopoverListener(flag) { let timer = setTimeout(() => { let scrollElement = this.$refs.multipleTable.$el.querySelector('.el-table__body-wrapper'); console.log('监听滚动,用于编辑框的滚动移除', flag, scrollElement); // let scrollHandle = () => { console.log('执行--->', this.visibleEditOpinions); if (this.visibleEditOpinions) { this.clearEditPopperComponent(); } } if (flag) { // 滚动节流 scrollElement.addEventListener('scroll', throttle(500, scrollHandle)); } else { scrollElement.removeEventListener('scroll', scrollHandle); } clearTimeout(timer); }, 0); }, // 复选框选中的数据 changeSelection(row) { this.selectData = row; console.log('复选框选中的数据', this.selectData); this.seqs = this.selectData.map((el) => { return el.seq; }).toString(); console.log('seqs---->', this.seqs); }, // 清空编辑组件 clearEditPopperComponent() { this.prevTarget = null; this.popperFlag = !this.popperFlag; this.visibleEdit = false; }, // 点击编辑 handleClickEdit(row, e) { //阻止事件冒泡,兼容ie if (event.stopPropagation) { event.stopPropagation(); } else if (window.event) { window.event.cancelBubble = true; } let currentTarget = e.target; // 赋值当前点击的编辑 this.editData = row; // 设置编辑数据 // 判断是否需要切换 if (this.prevTarget === currentTarget) { // 同一个元素重复点击 this.visibleEdit = !this.visibleEdit; } else { // 切换不同元素, 判断之前是否有点击其他编辑 prevTarget if (this.prevTarget) { // 先清除之前的编辑框 this.clearEditPopperComponent(); // 然后生成新的编辑框 this.$nextTick(() => { this.prevTarget = currentTarget; this.visibleEdit = true; }); } else { // 首次 console.log('首次--->this.prevTarget'); this.prevTarget = currentTarget; this.visibleEdit = true; } } } } }; </script>
注意点
1、fixed 定位导致的列表行错位
2、监听滚动函数名必须具名,不然滚动的时候会导致内存问题,浏览器直接崩溃,也不能移出对应的滚动事件
3、reference 这个属性 element 文档只说了 slot 的使用,需要去看源码
为什么要用reference这样做的原因?
如果将 el-popoper 写在表格的编辑里,使用 slot 的话,表格数据一多就会有性能问题,页面很卡数据加载很慢,并且每次点击其他的编辑,会导致组件更新多次,另外,滚动的时候需要关闭,不然会编辑框滚来滚去,滚动的时候就需要考虑节流的问题。这样一来就基本在能接受的范围内。
js 库连接
popover.js
throttle-debounce