elementUI table 組件實現自定義列、寬度、排序并聯動同步
最近在項目中有這樣一個需求,基于 elementUI的table 組件如何實現拖動修改列寬度,并同步在多個表格中,這個功能其實大家也挺常見的,所以既然遇到了,就總結一下,方便日后再遇到時遺忘掉相關知識,也為新朋友提供參考價值。
我們的目的是:針對于不同的人群,顯示不同的字段,不同的排序規則(index、fixed)。那好,我們先來分析一下實現這樣的功能都需要做什么。
前期調研
elementUI 支持那些功能、回調?
- 寬度控制
- 寬度是否可以通過參數控制? 提供,給?
el-table-column
?組件添加?width
?屬性即可。 - 參數是首次有效,還是動態更新?動態更新所以可以使用?
:width
。 - 是否提供了拖拽調整寬度的方案?添加?
border
?,并且開啟?resizable
?(默認開啟)。- 是否提供了回調函數?
header-dragend(newWidth, oldWidth, column, event)
?當拖動表頭改變了列的寬度的時候會觸發該事件 - 是否提供了API用于獲取當前寬度配置?沒有提供
- 是否提供了回調函數?
- 寬度是否可以通過參數控制? 提供,給?
- 字段順序
- 順序是否可以通過參數控制?沒提供,看了一遍并且搜索?排序、順序、index?等關鍵詞并無收獲。主要排序能力都是對內容區域。
- 如果無法通過參數配置,那么通過什么地方可以影響到排序規則?我們可以通過修改?
<el-table-column>
?的順序來控制。
分析
經過調研 elementUI 發現可以近乎完成這項工作,那么我們就不考慮其他方案了。只把獲取當前寬度配置這一個問題解決就好了。
思考一下,怎么改寬度?這不就 style="width: 10px"
?行內樣式嘛,這也太簡單了。
打開控制臺一看,草率😅了,干干凈凈什么都沒有。這就離譜了,魔法嗎?哈哈,當然不是,我們可以看到有個 colgroup
、col
?標簽,專門用來控制列寬。
那就簡單了,我們直接獲取即可。
實現代碼
寬度控制(自帶)
重點是加?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>
[email protected]
通過?@header-dragend
?拿到通知,然后去獲取節點上的真實數據
headerdragend(newWidth, oldWidth, column, e) { // 獲取到觸發節點,也就是你拖動的是哪一個 var el = e.target; // 獲取到當前 table 的 colgroup col 節點,用于后面獲取寬度 // getParentNodes 是一個模仿 $(el).parents() 的方法 var colList = getParentNodes(el, 'table').querySelectorAll('colgroup col'); // 獲取當前拖動的是第幾個,方便后續檢測 DOM 是否已更新 var currentColIndex = this.tableTitleList.findIndex(item=>item.label == column.label); if(currentColIndex == -1){ return console.warn('找不到拖動列') } // 修改配置列表,把當前列設置為固定寬度 this.tableTitleList[currentColIndex].widthEnable = true; // 起了一個定時任務去獲取最終的寬度 clearInterval(headerDragendInterval) headerDragendInterval = setInterval(()=>{ // 判斷一下目標列的寬度是否為最終寬度 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) }
控制順序
因為數組是有順序的嘛,所以使用 v-for
來循環,然后改變數組中的順序,就可以改變渲染出來的內容順序。
<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>
拖動排序
這塊我直接使用 Sortable
來實現功能,正好也是群里一個人問的。在 onEnd
的時候把操作同步到數據源就OK了。
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] ) } }) },
完結,拿走不謝。
聲明:
1. 本站所有文章教程及資源素材均來源于網絡與用戶分享或為本站原創,僅限用于學習和研究。
2. 如果內容損害你的權益請聯系客服QQ:1642748312給予處理。
碼云筆記 » elementUI table 組件實現自定義列、寬度、排序并聯動同步
1. 本站所有文章教程及資源素材均來源于網絡與用戶分享或為本站原創,僅限用于學習和研究。
2. 如果內容損害你的權益請聯系客服QQ:1642748312給予處理。
碼云筆記 » elementUI table 組件實現自定義列、寬度、排序并聯動同步