vue2中el-tree组件实现双击树的节点来修改节点名称

目标

  • 在没双击之前,树的节点是文本样式。
  • 在双击之后,节点位置变成输入框形式,原节点的名称显示在输入框中,可以进行修改。
  • 修改完毕之后,当输入框失去焦点的时候,输入框消失,又变成原本的文本样式,并且显示的是修改后的节点名称。

添加一个树

<template>
    <div>
        <el-tree
            :data="tree"
            highlight-current
            node-key="id"
            :props="{
                children: 'children',
                label: 'name'
            }"
            ref="tree"
        >
        </el-tree>
    </div>
</template>

<script>
export default {
    data() {
        return {
            tree: [
                {
                    id: 1,
                    name: '北京',
                    children: [
                        {
                            id: 5,
                            name: '朝阳',
                            children: [
                                {
                                    id: 17,
                                    name: '双塔',
                                    children: []
                                },
                                {
                                    id: 18,
                                    name: '龙城',
                                    children: []
                                }
                            ]
                        },
                        {
                            id: 6,
                            name: '丰台',
                            children: [
                                {
                                    id: 19,
                                    name: '新村',
                                    children: []
                                },
                                {
                                    id: 20,
                                    name: '大红门',
                                    children: []
                                },
                                {
                                    id: 21,
                                    name: '长辛店',
                                    children: [
                                        {
                                            id: 22,
                                            name: '东山坡',
                                            children: []
                                        },
                                        {
                                            id: 23,
                                            name: '北关',
                                            children: []
                                        },
                                        {
                                            id: 24,
                                            name: '光明里',
                                            children: []
                                        },
                                        {
                                            id: 25,
                                            name: '赵辛店',
                                            children: []
                                        },
                                        {
                                            id: 26,
                                            name: '西峰寺',
                                            children: []
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            id: 7,
                            name: '海淀',
                            children: []
                        },
                        {
                            id: 8,
                            name: '房山',
                            children: []
                        },
                        {
                            id: 10,
                            name: '顺义',
                            children: []
                        }
                    ]
                },
                {
                    id: 2,
                    name: '上海',
                    children: [
                        {
                            id: 11,
                            name: '黄埔',
                            children: []
                        },
                        {
                            id: 12,
                            name: '徐汇',
                            children: []
                        }
                    ]
                },
                {
                    id: 3,
                    name: '广州',
                    children: [
                        {
                            id: 13,
                            name: '荔湾',
                            children: []
                        },
                        {
                            id: 14,
                            name: '白云',
                            children: []
                        },
                        {
                            id: 15,
                            name: '越秀',
                            children: []
                        },
                        {
                            id: 16,
                            name: '南沙',
                            children: []
                        }
                    ]
                }
            ]
        }
    }
}
</script>

效果

实现

基本思路

利用插槽的方式定义树的每个节点

https://element.eleme.cn/#/zh-CN/component/tree#zi-ding-yi-jie-dian-nei-rong

然后在定义节点的时候添加一个文本,一个输入框

通过设置文本的双击事件 dblclick 来操作

通过 v-ifv-else 来达到只同时显示一个

当双击节点后,激活变量,然后隐藏文本,显示输入框,并把节点名给文本框绑定的变量

修改后,失去焦点的时候,修改树的数据或者提交给后端,然后修改激活的变量,显示文本,隐藏输入框。

完整代码

<template>
    <div>
        <el-tree
            :data="tree"
            highlight-current
            node-key="id"
            :props="{
                children: 'children',
                label: 'name'
            }"
            ref="tree"
        >
            <span class="custom-tree-node" slot-scope="{ node, data }" @dblclick="headerDbClick(data)">
                <span v-if="!data.isEdit">{{ node.label }}</span>
                <input
                    v-else
                    :ref="data.id"
                    placeholder="请输入内容"
                    v-model="currentName"
                    @blur="($event) => handleInputBlur($event, data)"
                />
            </span>
        </el-tree>
    </div>
</template>

<script>
export default {
    methods: {
        headerDbClick(data) {
            console.log('双击节点', data)
            this.currentName = data.name
            this.$set(data, 'isEdit', true)
            this.$nextTick(() => {
                this.$refs[data.id] && this.$refs[data.id].focus() // 获取输入框,自动获取焦点
            })
        },
        handleInputBlur(event, data) {
            console.log(event.target.value)
            const inputName = event.target.value.trim()
            if (inputName === '') {
                this.$message({
                    type: 'warning',
                    message: '分类名称不能为空,请重新输入'
                })
                this.$set(data, 'isEdit', false) // 让文本span标签显示,输入框隐藏
            } else if (inputName === data.name) {
                this.$set(data, 'isEdit', false)
            } else {
                this.$set(data, 'isEdit', false)
                data.name = inputName
            }
            this.currentName = ''
        }
    },
    data() {
        return {
            tree: [
                {
                    id: 1,
                    name: '北京',
                    children: [
                        {
                            id: 5,
                            name: '朝阳',
                            children: [
                                {
                                    id: 17,
                                    name: '双塔',
                                    children: []
                                },
                                {
                                    id: 18,
                                    name: '龙城',
                                    children: []
                                }
                            ]
                        },
                        {
                            id: 6,
                            name: '丰台',
                            children: [
                                {
                                    id: 19,
                                    name: '新村',
                                    children: []
                                },
                                {
                                    id: 20,
                                    name: '大红门',
                                    children: []
                                },
                                {
                                    id: 21,
                                    name: '长辛店',
                                    children: [
                                        {
                                            id: 22,
                                            name: '东山坡',
                                            children: []
                                        },
                                        {
                                            id: 23,
                                            name: '北关',
                                            children: []
                                        },
                                        {
                                            id: 24,
                                            name: '光明里',
                                            children: []
                                        },
                                        {
                                            id: 25,
                                            name: '赵辛店',
                                            children: []
                                        },
                                        {
                                            id: 26,
                                            name: '西峰寺',
                                            children: []
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            id: 7,
                            name: '海淀',
                            children: []
                        },
                        {
                            id: 8,
                            name: '房山',
                            children: []
                        },
                        {
                            id: 10,
                            name: '顺义',
                            children: []
                        }
                    ]
                },
                {
                    id: 2,
                    name: '上海',
                    children: [
                        {
                            id: 11,
                            name: '黄埔',
                            children: []
                        },
                        {
                            id: 12,
                            name: '徐汇',
                            children: []
                        }
                    ]
                },
                {
                    id: 3,
                    name: '广州',
                    children: [
                        {
                            id: 13,
                            name: '荔湾',
                            children: []
                        },
                        {
                            id: 14,
                            name: '白云',
                            children: []
                        },
                        {
                            id: 15,
                            name: '越秀',
                            children: []
                        },
                        {
                            id: 16,
                            name: '南沙',
                            children: []
                        }
                    ]
                }
            ],
            currentName: ''
        }
    }
}
</script>
posted @ 2024-02-06 11:07  厚礼蝎  阅读(664)  评论(0编辑  收藏  举报