el-table樹(shù)形表格中復(fù)選框聯(lián)動(dòng)功能操作大全
最終效果:

需求描述:
1.父級(jí)復(fù)選框可控制子級(jí)復(fù)選框狀態(tài):點(diǎn)擊父級(jí)復(fù)選框選中或不選中時(shí),子級(jí)復(fù)選框根據(jù)父級(jí)狀態(tài)更新選中狀態(tài)。
2.子級(jí)復(fù)選框不可控制父級(jí)復(fù)選框狀態(tài):子級(jí)復(fù)選框全選時(shí),不會(huì)默認(rèn)勾選父級(jí)復(fù)選框。父級(jí)全選后取消所有子級(jí)復(fù)選框,父級(jí)復(fù)選框狀態(tài)不會(huì)改變。
解決方法:
我的思路是給table列表數(shù)據(jù)添加一個(gè)標(biāo)識(shí) (isCheck = false),通過(guò)點(diǎn)擊復(fù)選框改變標(biāo)識(shí),再通過(guò)標(biāo)識(shí)來(lái)控制復(fù)選框選中狀態(tài)。
基礎(chǔ)代碼
<el-table
ref="treeTable"
v-loading="loading"
:data="tableList"
row-key="id"
stripe
class="table_hei296"
:expand-row-keys="expandRowKeys"
@select="handleSelection"
@select-all="selectAll"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
>
<el-table-column type="selection" width="55" align="center" :selectable="handleSelectable"/>
<el-table-column type="index" width="55" align="center" label="序號(hào)"/>
<el-table-column prop="name" label="類(lèi)名稱(chēng)" show-overflow-tooltip />
<el-table-column prop="code" label="編碼" show-overflow-tooltip />
<el-table-column prop="groupType" label="組別" show-overflow-tooltip />
</el-table>1.初始化table列表數(shù)據(jù)。
initCheckedBox() {
const initList = function(data) {
data.forEach(function(item) {
item.isCheck = false // 未選中
if (item.children) {
initList(item.children)
}
})
return data
}
this.rightCheckList = initList(this.tableList)
},2.當(dāng)用戶(hù)手動(dòng)勾選全選 Checkbox 時(shí)觸發(fā)的事件
// 當(dāng)用戶(hù)手動(dòng)勾選全選 Checkbox 時(shí)觸發(fā)的事件
selectAll(selection) {
if (!this.checkAll) {
this.checkAll = true
this.isAllChecked(this.rightCheckList, true)
} else {
this.checkAll = false
this.isAllChecked(this.rightCheckList, false)
}
const selectCheck = this.$getNodesIterative(this.rightCheckList, 'children', 'isCheck', true)
this.selectedRows = selectCheck.map(item => item.id)
},
// 是否全選中
isAllChecked(data, status) {
if (data === undefined) {
const imitData = []
imitData.push(data)
} else {
data.forEach(item => {
item.isCheck = item.parentId === 0 ? false : status
this.$refs.treeTable.toggleRowSelection(item, item.isCheck)
if (item.children) {
this.isAllChecked(item.children, status)
}
})
}
},checkAll默認(rèn)false
3.當(dāng)用戶(hù)手動(dòng)勾選數(shù)據(jù)行的 Checkbox 時(shí)觸發(fā)的事件
handleSelection(selection, row) {
row.isCheck = !row.isCheck
if(row.children.length === 0 && row.isCheck === true){
this.checkedParentRow(row, this.rightCheckList)
} else if(row.children.length === 0 && row.isCheck === false){
this.clearParentRow(row, this.rightCheckList)
} else if(row.children.length > 0 && row.isCheck === true){
this.isAllChecked(row.children, true)
} else if(row.children.length > 0 && row.isCheck === false){
this.isAllChecked(row.children, false)
}
const selectCheck = this.$getNodesIterative(this.rightCheckList, 'children', 'isCheck', true)
this.selectedRows = selectCheck.map(item => item.id)
},
// 選中子節(jié)點(diǎn)默認(rèn)選中父節(jié)點(diǎn),暫時(shí)不用,這段與需求不同,可不寫(xiě)。
// 如果有這個(gè)需求可寫(xiě),并取消if隱藏代碼
checkedParentRow(data, obj) {
for(var item in obj){
if(obj[item].id === data.parentId){
var every = obj[item].children.every(function(item) {
return item.isCheck === true
})
// if (every) {
// obj[item].isCheck = true
// this.$refs.treeTable.toggleRowSelection(obj[item], true)
// }
}
}
},
// 子節(jié)點(diǎn)都未被選中,父節(jié)點(diǎn)默認(rèn)取消選中
clearParentRow(data, obj) {
const parentRow = this.$findTreeObjById(obj, 'id', data.parentId)
parentRow.isCheck = false
this.$refs.treeTable.toggleRowSelection(parentRow, false)
},this.$getNodesIterative與this.$findTreeObjById寫(xiě)成了全局方法,如下:
/**
*
* @param {Array} treeList 樹(shù)形數(shù)據(jù)
* @param {string} targetType 樹(shù)形數(shù)據(jù)中所查找的鍵值
* @param {string} target 樹(shù)形數(shù)據(jù)中所查找的值
* @returns
*/
export function findTreeObjById(treeList, targetType, target) {
for (const item of treeList) {
// 匹配當(dāng)前節(jié)點(diǎn)
if (item[targetType] === target) return item;
// 遞歸查找子節(jié)點(diǎn)
if (item.children && item.children.length > 0) {
const res = findTreeObjById(item.children, targetType, target);
if (res) return res;
}
}
return null; // 無(wú)匹配
}
/**
* 提取樹(shù)形結(jié)構(gòu)中所有type為true的節(jié)點(diǎn)(迭代版,避免棧溢出)
* @param {Array} tree 樹(shù)形結(jié)構(gòu)數(shù)組
* @param {string} childrenKey 子節(jié)點(diǎn)字段名
* @param {string} key 判斷鍵值
* @param flagValue 判斷鍵值
* @returns {Array} 平級(jí)的符合條件的節(jié)點(diǎn)數(shù)組
*/
export function getNodesIterative(tree, childrenKey, key, flagValue) {
const result = [];
// 用棧存儲(chǔ)待遍歷的節(jié)點(diǎn)(初始為根節(jié)點(diǎn)數(shù)組)
const stack = [...tree];
while (stack.length > 0) {
const node = stack.pop(); // 棧頂取出節(jié)點(diǎn)(也可用shift()實(shí)現(xiàn)隊(duì)列,效率略低)
// 篩選type為true的節(jié)點(diǎn)
if (node[key] === flagValue) {
result.push({ ...node });
}
// 子節(jié)點(diǎn)入棧(繼續(xù)遍歷)
if (Array.isArray(node[childrenKey])) {
stack.push(...node[childrenKey]);
}
}
return result;
}
export default {
findTreeObjById,
getNodesIterative
}總結(jié):
這個(gè)功能兩個(gè)項(xiàng)目中都用到了,所以記錄下~
提醒自己:這段代碼寫(xiě)了兩三年了,沒(méi)做優(yōu)化,后面記得優(yōu)化一下呀~
到此這篇關(guān)于el-table樹(shù)形表格中,復(fù)選框聯(lián)動(dòng)功能的文章就介紹到這了,更多相關(guān)el-table復(fù)選框聯(lián)動(dòng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
electron+vue3實(shí)現(xiàn)自動(dòng)更新的示例代碼
本文主要介紹了electron+vue3實(shí)現(xiàn)自動(dòng)更新的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-10-10
詳解polyfills如何按需加載及場(chǎng)景示例詳解
這篇文章主要為大家介紹了詳解polyfills如何按需加載及場(chǎng)景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
vue3+vite多項(xiàng)目多模塊打包(基于vite-plugin-html插件)
這篇文章主要給大家介紹了關(guān)于vue3+vite基于vite-plugin-html插件實(shí)現(xiàn)多項(xiàng)目多模塊打包的相關(guān)資料,現(xiàn)在很多小伙伴都已經(jīng)使用Vite+Vue3開(kāi)發(fā)項(xiàng)目了,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07
vue中radio單選框如何實(shí)現(xiàn)取消選中狀態(tài)問(wèn)題
這篇文章主要介紹了vue中radio單選框如何實(shí)現(xiàn)取消選中狀態(tài)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05
Vue使用ResizeObserver輕松監(jiān)聽(tīng)元素尺寸變化
在前端開(kāi)發(fā)中,我們經(jīng)常需要知道一個(gè)元素的尺寸是否發(fā)生了變化,過(guò)去,我們只能通過(guò)監(jiān)聽(tīng)window的resize事件,無(wú)法監(jiān)聽(tīng)具體元素的變化,ResizeObserver應(yīng)運(yùn)而生,它可以幫助我們監(jiān)聽(tīng)任意元素的大小變化,所以本文為大家介紹了如何使用ResizeObserver監(jiān)聽(tīng)元素尺寸變化2025-11-11
Vue3中watch監(jiān)聽(tīng)的五種情況詳解
watch函數(shù)用于偵聽(tīng)某個(gè)值的變化,當(dāng)該值發(fā)生改變后,觸發(fā)對(duì)應(yīng)的處理邏輯,本文將給大家介紹了Vue3中watch監(jiān)聽(tīng)的五種情況,文中通過(guò)代碼示例講解的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下2024-03-03
uniapp組件uni-file-picker中設(shè)置使用照相機(jī)和相冊(cè)權(quán)限的操作方法
這篇文章主要介紹了uniapp組件uni-file-picker中設(shè)置使用照相機(jī)和相冊(cè)的權(quán)限,在uniapp中,我們通常會(huì)使用uni-file-picker這個(gè)組件,但是這個(gè)組件中,有點(diǎn)缺陷,就是沒(méi)有對(duì)這個(gè)功能的傳值設(shè)置,這里就要給組件進(jìn)行修改了,需要的朋友可以參考下2022-11-11

