1. 程式人生 > 實用技巧 >ElementUI Tree 元件,實現自定義勾選父子選項

ElementUI Tree 元件,實現自定義勾選父子選項

目錄

建立時間:2020-11-02

為什麼要自定義實現勾選,而不是採用其自帶的勾選?

  1. 當設定了:複選框 和 check-strictly = false(預設) 父子關聯,會出現:

    • 選中父級,勾選所有子選項;取消父級選中,同時取消子選項勾選
    • 選中子選項,父選項變為半選中狀態,如果勾選所有子選項,父選項為選中狀態
  2. 當設定了:複選框 和 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()]
}

程式碼核心功能說明:

  1. 判斷點選是選中操作,還是取消選中操作

  2. 如果是選中,則遞迴的去選中其父級,以及其所有子選項

  3. 如果是取消選中,則遞迴的將子選項的狀態改為非選中

歡迎交流 Github