需求
記錄下最近項目遇到的奇怪需求:使用el-tree實現(xiàn)樹狀圖的正向級聯(lián)和反向不級聯(lián)正卧,簡單說就是父級被選中子集節(jié)點也被選中蠢熄,子集節(jié)點被選中所有父級節(jié)點也要被選中,而子集節(jié)點取消選中父級節(jié)點依然是選中狀態(tài)......上圖:
大致就是這么個意思炉旷,歷經(jīng)坎坷終于搞出來了G┛住!窘行!
思路
將el-tree的默認勾選機制取消饥追,將處理過的數(shù)據(jù)手動渲染;
1罐盔、check-strictly:true; // 在顯示復選框的情況下但绕,是否嚴格的遵循父子不互相關聯(lián)的做法,默認為 false惶看,設置為true則每一級勾選都相互獨立
2捏顺、統(tǒng)一處理數(shù)據(jù):勾選節(jié)點時反向遞歸出所有父級節(jié)點,再遞歸出所有子集節(jié)點碳竟,存儲
3草丧、統(tǒng)一渲染存儲的數(shù)據(jù)
具體實現(xiàn)
html:
v-loading="treeLoading"
:check-strictly="checkAbiut"
:ref="'tree' + index"
default-expand-all
show-checkbox
class="tree-line underTabsTree"
:data="treeData"
:props="defaultProps"
node-key="id"
:indent="0"
:default-checked-keys="defaultChecked"
@check-change="(data, checked, indeterminate) => handleNodeClick(data, checked, indeterminate, index)">
data:
treeLoading: false,
checkAbiut: true,
treeData: [],
defaultProps: {
children: "children",
label: "label"
},
defaultChecked: []
methods:
flatArry(list, flatList) { // 將樹的數(shù)據(jù)扁平化處理
for (let i = 0; i < list.length; i++) {
flatList.push(list[i]);
if (list[i].children.length > 0) {
this.flatArry(list[i].children, flatList);
}
}
},
getParent(list, data) { // 獲取勾選節(jié)點的所有父級節(jié)點(反向遞歸),push到數(shù)組
if (data.pid != null) {
let flatList = [];
let faData = [];
this.flatArry(this.treeData, flatList);
faData = flatList.filter(item => {
return item.id == data.pid;
});
if (list.indexOf(faData[0].id) == -1) {
list.push(faData[0].id);
}
this.getParent(list, faData[0]); // 選中
}
},
getSon(list, data) { // 獲取勾選節(jié)點的所有子節(jié)點莹桅,push到數(shù)組
for (let x = 0; x < data.children.length; x++) {
if (list.indexOf(data.children[x].id) == -1) {
list.push(data.children[x].id);
}
this.getSon(list, data.children[x]);
}
},
conseSon(list, data) { // 取消勾選時將所有子節(jié)點設為‘’
for (let x = 0; x < data.children.length; x++) {
if (list.indexOf(data.children[x].id) != -1) {// 數(shù)組里有
list[list.indexOf(data.children[x].id)] = "";
this.conseSon(list, data.children[x]);
}
}
},
editPermission(list, data, slected) { // 勾選對數(shù)據(jù)進行處理
if (slected) { // 選中
if (list.indexOf(data.id) == -1) { // 數(shù)組里沒有
list.push(data.id);
this.getSon(list, data);
if (data.id != '0' && data.id != '' && data.id != null) {
this.getParent(list, data);
}
}
} else { // 取消選中
if (list.indexOf(data.id) != -1) { // 數(shù)組里有
list[list.indexOf(data.id)] = "";
this.conseSon(list, data);
}
}
},
handleNodeClick(data, checked, indeterminate, index) { // 勾選觸發(fā)的函數(shù)昌执,choosedList為存儲最終數(shù)據(jù)的數(shù)組
this.editPermission(this.choosedList, data, checked);
this.$nextTick(() => { // 一定要放在nextTick否則可能渲染不出來
let choosedList = this.choosedList.filter((item) => {? return item != ''})
this.$refs[`tree${index}`][0].setCheckedKeys(choosedList); // this.$refs[`tree${index}`][0]寫法時因為tree在v-for模塊里的,若是只有一個單獨的tree則[0]不需要復制代碼
});
},
總結
這個需求改了很多版诈泼,導致最后這一版有一種無從下手的感覺懂拾,后來靜下心來捋一捋,思路清晰了寫的也很快铐达,希望對你有點幫助岖赋。PS:本人能力有限,僅供參考瓮孙,歡迎交流唐断,勿噴謝謝选脊。