目标
- 在没双击之前,树的节点是文本样式。
- 在双击之后,节点位置变成输入框形式,原节点的名称显示在输入框中,可以进行修改。
- 修改完毕之后,当输入框失去焦点的时候,输入框消失,又变成原本的文本样式,并且显示的是修改后的节点名称。
添加一个树
<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-if
和 v-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>
标签:el,name,children,输入框,双击,节点,data,id
From: https://www.cnblogs.com/guangdelw/p/18009397