創建時間:2020-11-02
為什么要自定義實現勾選,而不是采用其自帶的勾選?
-
當設置了:復選框 和
check-strictly = false(默認)
父子關聯,會出現:- 選中父級,勾選所有子選項;取消父級選中,同時取消子選項勾選
- 選中子選項,父選項變為半選中狀態,如果勾選所有子選項,父選項為選中狀態
-
當設置了:復選框 和
check-strictly = true
父子無關聯,會出現:- 父級的選中和取消選中,都不會對子選項的狀態有任何的影響
- 子選項的選中和取消,都不會對父選項的狀態有任何的影響
綜合上述現象:如果想單獨只選中父選項,不選擇任一子選項,功能無法實現,所以采用自定義勾選
實現步驟
既然使用自定義勾選,所以采用 check-strictly = true
父子無關聯
html 代碼
<el-tree
ref="cusTreeRef"
show-checkbox
check-strictly
default-expand-all
node-key="id"
:data="treeData"
:props="defaultProps"
@check="handleCheck">
</el-tree>
<p>
<b>當前選中</b> <span>{{ cusChecked }}</span>
</p>
vue 代碼
data () {
return {
defaultProps: {
children: 'children',
label: 'label'
},
treeData: [{
id: 1,
label: '一級 1',
children: [{
id: 4,
label: '二級 4',
children: [{
id: 9,
label: '三級 9'
}, {
id: 10,
label: '三級 10',
children: [{
id: 11,
label: '四級級 11'
}, {
id: 12,
label: '四級級 12'
}]
}]
}]
}],
cusChecked: []
}
}
handleCheck (currentNode, treeStatus) {
console.log(currentNode, treeStatus)
/**
* @des 根據父元素的勾選或取消勾選,將所有子級處理為選擇或非選中狀態
* @param { node: Object } 當前節點
* @param { status: Boolean } (true : 處理為勾選狀態 ; false: 處理非選中)
*/
const setChildStatus = (node, status) => {
/* 這里的 id children 也可以是其它字段,根據實際的業務更改 */
this.$refs.cusTreeRef.setChecked(node.id, status)
if (node.children) {
/* 循環遞歸處理子節點 */
for (let i = 0; i < node.children.length; i++) {
setChildStatus(node.children[i], status)
}
}
}
/* 設置父節點為選中狀態 */
const setParentStatus = (nodeObj) => {
/* 拿到tree組件中的node,使用該方法的原因是第一次傳入的 node 沒有 parent */
const node = this.$refs.cusTreeRef.getNode(nodeObj)
if (node.parent.key) {
this.$refs.cusTreeRef.setChecked(node.parent, true)
setParentStatus(node.parent)
}
}
/* 判斷當前點擊是選中還是取消選中操作 */
if (treeStatus.checkedKeys.includes(currentNode.id)) {
setParentStatus(currentNode)
setChildStatus(currentNode, true)
} else {
/* 取消選中 */
if (currentNode.children) {
setChildStatus(currentNode, false)
}
}
this.cusChecked = [...this.$refs.cusTreeRef.getCheckedKeys()]
}
代碼核心功能說明:
-
判斷點擊是選中操作,還是取消選中操作
-
如果是選中,則遞歸的去選中其父級,以及其所有子選項
-
如果是取消選中,則遞歸的將子選項的狀態改為非選中
歡迎交流 Github