element-ui Tree組件動(dòng)態(tài)操作節(jié)點(diǎn)

Element-ui/Tree/異步加載數(shù)據(jù)/node節(jié)點(diǎn)操作

在項(xiàng)目當(dāng)中,有遇到需要?jiǎng)討B(tài)操作element-ui中Tree組件的節(jié)點(diǎn)的需求,官方提供的方案是一次性的加載所有數(shù)據(jù),然后通過(guò)操作這一組數(shù)據(jù)來(lái)實(shí)現(xiàn)對(duì)于node節(jié)點(diǎn)的增刪改。但是因?yàn)槲矣龅降那闆r是數(shù)據(jù)層級(jí)不確定,不能夠一次加載所有數(shù)據(jù)的情況下,對(duì)于節(jié)點(diǎn)進(jìn)行增刪改的操作,因?yàn)楦杏X(jué)異步加載數(shù)據(jù)和node節(jié)點(diǎn)操作有點(diǎn)互斥,我只能另辟蹊徑來(lái)試下這個(gè)功能。以下是我實(shí)現(xiàn)的主要思路:

  1. 數(shù)據(jù)操作都放在后臺(tái)進(jìn)行,前端只做數(shù)據(jù)的展示
  2. 用官方的方式進(jìn)行tree數(shù)據(jù)的異步加載
  3. 用一個(gè)數(shù)組treeExpandedKeys配合default-expanded-keys屬性來(lái)記錄已展開(kāi)的節(jié)點(diǎn)id
  4. 通過(guò)監(jiān)聽(tīng)node-expandnode-collapse事件來(lái)操作數(shù)組treeExpandedKeys的增刪
  5. 每次必要的操作通過(guò)刷新tree的key值來(lái)強(qiáng)制刷新Tree節(jié)點(diǎn)

具體代碼如下

<style lang="less">
    
</style>

<template>
    <article>
        <el-tree
            ref="tree"
            node-key="id"
            :key="treeKey"
            :data="data"
            :props="defaultProps"
            :default-expanded-keys="treeExpandedKeys"
            :expand-on-click-node="false"
            :lazy="true"
            :load="loadTreeNode"
            @node-expand="treeExpand"
            @node-collapse="treeCollapse">
        <span class="custom-tree-node" slot-scope="{ node, data }">
            <span>{{ node.label }}</span>
            <span class="custom__tree__icons">
                <el-tooltip class="item" effect="dark" content="新增" placement="top">
                    <i class="tree-icon el-icon-plus" @click="() => append(data)"></i>
                </el-tooltip>
                <el-tooltip class="item" effect="dark" content="編輯" placement="top">
                    <i class="tree-icon el-icon-edit" @click="() => edit(node, data)"></i>
                </el-tooltip>
                <el-tooltip class="item" effect="dark" content="刪除" placement="top">
                    <i class="tree-icon el-icon-close" @click="() => remove(node, data)"></i>
                </el-tooltip>
            </span>
        </span>
        </el-tree>
        <el-dialog top="5vh" class="dialog" title="新增子節(jié)點(diǎn)" :visible.sync="isShowDlg" width="500px"
                   :close="treeEditClose">
            <el-form :inline="true" label-width="120px" ref="nodeQuery"
                     :model="nodeQuery" size="small" class="demo-form-inline">
                <el-form-item label="子節(jié)點(diǎn)名稱(chēng)" prop="name">
                    <el-input placeholder="請(qǐng)輸入子節(jié)點(diǎn)名稱(chēng)" v-model="nodeQuery.name"></el-input>
                </el-form-item>
                <el-form-item class="btns__adjust">
                    <el-button size="medium" type="primary" @click="sure">確定</el-button>
                    <el-button size="medium" @click="reset">取消</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    </article>
</template>

<script>
    export default {
        data() {
            return {
                data: [], // tree數(shù)據(jù)源
                defaultProps: { // 樹(shù)相關(guān)屬性設(shè)置
                    id: "",
                    children: "childList",
                    label: "name",
                    isLeaf: 'leaf'
                },
                activeData: null,   // 當(dāng)前操作數(shù)據(jù)
                treeExpandedKeys: [],   // 記錄打開(kāi)節(jié)點(diǎn)的數(shù)組
                treeKey: '',    // 控制tree渲染的key
                nodeQuery: {
                    name: ''    // 編輯樹(shù)節(jié)點(diǎn)表單的model
                },
                isShowDlg: false    // 是否顯示編輯節(jié)點(diǎn)彈框
            };
        },
        methods: {
            // 加載樹(shù)
            loadTreeNode(node, resolve) {
                const id = node ? node.data.id : '';
                getTreeData({id}).then(re => {
                    const result = re.data;
                        const treeData = result.data;
                    if (result.success && node.level === 0) {
                        // 如果是第一次加載數(shù)據(jù),直接返回?cái)?shù)據(jù)
                        resolve(treeData);
                    } else if(result.success) {
                        // 如果非第一次加載數(shù)據(jù),將返回?cái)?shù)據(jù)拼接到操作節(jié)點(diǎn)的childList屬性中
                        node.data.childList = treeData;
                        resolve(treeData);
                    } else {
                        resolve([]);
                        this.$message({
                            type: 'error',
                            message: '加載數(shù)據(jù)出錯(cuò)!'
                        });
                    }
                });
            },

            // 新增節(jié)點(diǎn)
            append(data) {
                this.editType = "ADD";
                this.isShowDlg = true;
                // 記錄當(dāng)前節(jié)點(diǎn)數(shù)據(jù),供新增彈框關(guān)閉后回調(diào)用
                this.activeData = data;
            },

            // 移除節(jié)點(diǎn)
            remove(node, data) {
                removeNode(data.id).then(re => {
                    const result = re.data;
                    if (result && result.success) {
                        // 重新渲染tree
                        this.renderTree();
                        this.$message({
                            type: "success",
                            message: "刪除成功!"
                        });
                    }
                });
            },

            // 編輯節(jié)點(diǎn)
            edit(node, data) {
                this.nodeQuery.name = data.name;
                // 記錄當(dāng)前操作數(shù)據(jù)
                this.activeData = data;
                this.editType = "EDIT";
                this.isShowDlg = true;
            },

            // 新增節(jié)點(diǎn)回調(diào)函數(shù)
            appendCallback() {
                const data = this.activeData;
                const nodeQuery = this.nodeQuery;
                nodeQuery.parentId = data.id === '0' ? '' : data.id;
                // 將新節(jié)點(diǎn)名稱(chēng)和父節(jié)點(diǎn)id傳遞到后臺(tái)
                addNode(nodeQuery).then(re => {
                    this.renderTree();
                });
            },

            // 編輯節(jié)點(diǎn)回調(diào)函數(shù)
            editCallback() {
                const data = this.activeData,
                    nodeQuery = this.nodeQuery;
                data.name = nodeQuery.name;
                // 將節(jié)點(diǎn)新名稱(chēng)和節(jié)點(diǎn)id傳遞到后臺(tái)
                editNode(data).then(re => {
                    const result = re.data;
                    if (result && result.success) {
                        this.$message({
                            type: "success",
                            message: "修改成功!"
                        });
                        this.renderTree();
                    }
                });
            },

            // 刷新key值,重新渲染tree
            renderTree() {
                this.treeKey = +new Date();
            },

            // 當(dāng)節(jié)點(diǎn)打開(kāi)時(shí),記錄下打開(kāi)節(jié)點(diǎn)的id
            treeExpand(data, node, self) {
                this.treeExpandedKeys.push(data.id);
            },

            // 當(dāng)節(jié)點(diǎn)關(guān)閉時(shí),移除節(jié)點(diǎn)的id
            treeCollapse(data) {
                const index = treeExpandedKeys.indexOf(data.id);
                if (index > -1) {
                    this.treeExpandedKeys.splice(index, 1);
                }
            },

            // tree noed 新增/編輯確定事件
            sure() {
                const editType = this.editType;
                this.$refs["parentNodeQuery"].validate(valid => {
                    if (valid) {
                        editType === "ADD" ? this.appendCallback() : this.editCallback();
                        this.reset();
                    } else {
                        console.log("error submit!!");
                        return false;
                    }
                });
            },

            // tree node 彈框取消事件
            reset() {
                this.activeData = null;
                this.isShowDlg = false;
                this.nodeQuery = {
                    name: "",
                    parentId: ""
                };
                this.editType = "ADD";
            }
        }
    };
</script>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1、通過(guò)CocoaPods安裝項(xiàng)目名稱(chēng)項(xiàng)目信息 AFNetworking網(wǎng)絡(luò)請(qǐng)求組件 FMDB本地?cái)?shù)據(jù)庫(kù)組件 SD...
    陽(yáng)明AI閱讀 16,171評(píng)論 3 119
  • —1— “村上春樹(shù)說(shuō)過(guò)你要記得那些黑暗中默默抱緊你的人,逗你笑的人,陪你徹夜聊天的人,坐車(chē)來(lái)看望你的人,陪你哭...
    涵瑜姑娘閱讀 1,912評(píng)論 14 4
  • 別人總夸你骨子里有種氣場(chǎng) 說(shuō)是敢愛(ài)敢恨敢斷腸 但凡遇到心儀的人啊 就心心念想著如何把被單和床 都塞到懷里連同自己一...
    榴蓮姑娘233閱讀 376評(píng)論 0 0
  • ■文/芊墨之戀 愛(ài)這東西,挺怪的 你不知道它到底長(zhǎng)什么樣 總是在心里生長(zhǎng)著溫暖 像水波漣漪一樣 生成,散開(kāi),蔓延,...
    芊墨之戀閱讀 204評(píng)論 0 3

友情鏈接更多精彩內(nèi)容