基于 elementUI table 組件實(shí)現(xiàn)自定義列、寬度、排序并聯(lián)動(dòng)同步
作者:linong
來源:SegmentFault 思否社區(qū)
哈嘍,大家好又是我。昨天有個(gè)人在群里問:“基于 elementUI 如何實(shí)現(xiàn)拖動(dòng)修改列寬度,并同步在多個(gè)表格中”。
這個(gè)功能其實(shí)聽常見的,在不同的使用者眼中關(guān)注點(diǎn)就應(yīng)該是不一樣的。比如:
項(xiàng)目的主管,更關(guān)心進(jìn)度 前端開發(fā),關(guān)心設(shè)計(jì)稿、接口什么時(shí)候提供 后端開發(fā),關(guān)心前端什么時(shí)候?qū)懲?,什么時(shí)候聯(lián)調(diào) 測試人員,關(guān)心什么時(shí)候提測,以及對應(yīng)人員是誰
前期調(diào)研
elementUI 支持那些功能、回調(diào)?
寬度控制
是否提供了回調(diào)函數(shù)? header-dragend(newWidth, oldWidth, column, event)當(dāng)拖動(dòng)表頭改變了列的寬度的時(shí)候會(huì)觸發(fā)該事件是否提供了API用于獲取當(dāng)前寬度配置?沒有提供 寬度是否可以通過參數(shù)控制?提供,給 el-table-column組件添加width屬性即可。參數(shù)是首次有效,還是動(dòng)態(tài)更新?動(dòng)態(tài)更新所以可以使用 :width是否提供了拖拽調(diào)整寬度的方案?添加 border,并且開啟resizable(默認(rèn)開啟)。字段順序 順序是否可以通過參數(shù)控制?沒提供,看了一遍并且搜索 排序、順序、index 等關(guān)鍵詞并無收獲。主要排序能力都是對內(nèi)容區(qū)域。 如果無法通過參數(shù)配置,那么通過什么地方可以影響到排序規(guī)則?我們可以通過修改 <el-table-column>的順序來控制。
分析
style="width: 10px" 行內(nèi)樣式嘛,這也太簡單了。
colgroup、col 標(biāo)簽,專門用來控制列寬。
實(shí)現(xiàn)代碼
寬度控制(自帶)
border<el-table :data="tableData" border @header-dragend="headerdragend" style="width: 100%">
<el-table-column v-for="column in tableTitleList" :fixed="column.fixed" :prop="column.prop"
v-if="column.isShow"
:label="column.label" :width="column.width">
</el-table-column>
<el-table-column fixed="right" label="操作" width="100">
<template slot-scope="scope">
<el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>
<el-button type="text" size="small">編輯</el-button>
</template>
</el-table-column>
</el-table>
操作之后獲取寬度 @header-dragend
@header-dragend 拿到通知,然后去獲取節(jié)點(diǎn)上的真實(shí)數(shù)據(jù)headerdragend(newWidth, oldWidth, column, e) {
// 獲取到觸發(fā)節(jié)點(diǎn),也就是你拖動(dòng)的是哪一個(gè)
var el = e.target;
// 獲取到當(dāng)前 table 的 colgroup col 節(jié)點(diǎn),用于后面獲取寬度
// getParentNodes 是一個(gè)模仿 $(el).parents() 的方法
var colList = getParentNodes(el, 'table').querySelectorAll('colgroup col');
// 獲取當(dāng)前拖動(dòng)的是第幾個(gè),方便后續(xù)檢測 DOM 是否已更新
var currentColIndex = this.tableTitleList.findIndex(item=>item.label == column.label);
if(currentColIndex == -1){
return console.warn('找不到拖動(dòng)列')
}
// 修改配置列表,把當(dāng)前列設(shè)置為固定寬度
this.tableTitleList[currentColIndex].widthEnable = true;
// 起了一個(gè)定時(shí)任務(wù)去獲取最終的寬度
clearInterval(headerDragendInterval)
headerDragendInterval = setInterval(()=>{
// 判斷一下目標(biāo)列的寬度是否為最終寬度
if(colList[currentColIndex].width == newWidth){
this.changeColumnWidth(colList);
clearInterval(headerDragendInterval)
}else if(colList[currentColIndex].width == oldWidth){
console.info('需要等待渲染')
}else{
console.warn('異常值');
this.changeColumnWidth(colList);
clearInterval(headerDragendInterval)
}
}, 10)
}
控制順序
<el-table :data="tableData" border @header-dragend="headerdragend" style="width: 100%">
<el-table-column v-for="column in tableTitleList" :fixed="column.fixed" :prop="column.prop"
v-if="column.isShow"
:label="column.label" :width="column.width">
</el-table-column>
<el-table-column fixed="right" label="操作" width="100">
<template slot-scope="scope">
<el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button>
<el-button type="text" size="small">編輯</el-button>
</template>
</el-table-column>
</el-table>
拖動(dòng)排序
initSort(){
var el = document.querySelector('#sortWrap')
var that = this;
Sortable.create(el, {
delay: 100,
sort: !0,
forceFallback: !0,
scrollSensitivity: 100,
animation: 150,
ghostClass: "gift-ghost-item",
chosenClass: "gift-chosen-item",
onEnd: function(t) {
that.tableTitleList.splice(
t.newIndex,
0,
that.tableTitleList.splice(t.oldIndex, 1)[0]
)
}
})
},

評論
圖片
表情
