功能點
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 的話,表格資料一多就會有性能問題,頁面很卡資料加載很慢,并且每次點選其他的編輯,會導緻元件更新多次,另外,滾動的時候需要關閉,不然會編輯框滾來滾去,滾動的時候就需要考慮節流的問題。這樣一來就基本在能接受的範圍内。