实现效果图如下所示:
实际项目中使用,根据实际情况可参考挑选。代码如下:
<template>
<div class="tree-meum">
<el-tree :data="data" :highlight-current="true" :default-expand-all="true" :expand-on-click-node="false"
@node-click="(data) => onNodeClick(data, false)" node-key="id" :filter-node-method="filterNode" ref="tree">
<template v-slot="{ node, data }" class="show-hide custom-tree-node">
<span class="show-hide custom-tree-node">
<!-- <span>{{ data.name }}</span> -->
<!-- <span class="tree_node_label">{{showOrEdit(data)}}</span> -->
<span v-if="data.isEdit" class="inputsty">
<input ref="getfocus" type="text" class="node_input" :value=data.name
@blur="(ev) => edit_sure(ev, node, data)" @keyup.enter.native="(ev) => submitForm(ev, node, data)" />
</span>
<span v-else>{{ data.name }}</span>
<el-dropdown class="buttonList">
<span :class="['more', data.isEdit ? 'more_none' : '']">
···
</span>
<template #dropdown>
<el-dropdown-item @click="() => insertAfter(node, data)">
<el-button type="text" size="mini">
同级增加
</el-button>
</el-dropdown-item>
<el-dropdown-item @click="() => append(node, data)">
<el-button type="text" size="mini">
子集增加
</el-button>
</el-dropdown-item>
<el-dropdown-item @click="() => remove(node, data)">
<el-button type="text" size="mini">
删除
</el-button>
</el-dropdown-item>
<el-dropdown-item @click="(ev) => nodeEdit(ev, store, data)">
<el-button type="text" size="mini">
编辑
</el-button>
</el-dropdown-item>
</template>
</el-dropdown>
</span>
<!-- <span class="tree_node_label">{{showOrEdit(data)}}</span> -->
</template>
</el-tree>
</div>
</template>
<script>
import { componentTree, componentTreeCreate,componentTreeUpdate, treeDeleteComponentTreeId } from '@/api/busin'
export default {
components: {
},
props: {
},
data() {
return {
data: [],
filterText: '',
}
},
created() {
this.getTree()//初始化加载树
},
methods: {
async getTree() {
let result = await componentTree({})
this.data = result.data
},
//添加同级节点
insertAfter(node, data) {
const nodeList = node.parent.childNodes;
const curArr = node.parent.data.children || node.parent.data;
const index = curArr.findIndex(d => d.id === data.id) + 1;
new Promise((resolve, reject) => {
const newBrother = { id: data.parent_id, name: "", children: [], isEdit: true, type: 'add' };
curArr.splice(index, 0, newBrother);
resolve();
}).then(res => {
nodeList[index].checked = true;
this.$nextTick(() => {
this.$refs.getfocus.focus();
})
});
},
append(node, data) {
const newChild = { id: data.id, name: '', children: [], isEdit: true, type: 'add' };
if (!data.children) {
this.$set(data, 'children', []);
}
data.children.push(newChild);
this.$nextTick(() => {
this.$refs.getfocus.focus();
})
},
nodeEdit(ev, store, data) {
data.isEdit = true;
this.$nextTick(() => {
this.$refs.getfocus.focus();
});
},
//失焦事件
async edit_sure(ev, node, data) {
const $input =
ev.target.parentNode.parentNode.querySelector("input") ||
ev.target.parentElement.parentElement.querySelector("input");
if (!$input) {
return false;
} else if ($input.value == '') {
this.remove(node, data, 1)
} else {//赋值value
if (data.isEdit) {
if (data.type) {//增加
const res = await componentTreeCreate({ parent_id: data.id, name: $input.value })
if (res.data) {
data.name = $input.value;
data.isEdit = false;
this.getTree()
}
} else {//修改
const res = await componentTreeUpdate({ id: data.id, name: $input.value })
if (res.data) {
data.name = $input.value;
data.isEdit = false;
this.getTree()
}
}
}
}
},
async remove(node, data, type) {
const parent = node.parent;
const children = parent.data.children || parent.data;
const index = children.findIndex(d => d.id === data.id);
if (type == 1) {
return children.splice(index, 1);
}
await this.$messageBox.confirm(`您确定要删除吗`, '提示')
const res = await treeDeleteComponentTreeId(data.id)
if (res.data) {
this.getTree()
// children.splice(index, 1);
}
},
// 树节点 点击事件
async onNodeClick(data, stopRequestTree) {
},
submitForm(ev, node, data) {
this.edit_sure(ev, node, data)
},
filterNode(value, data) {
if (!value) return true;
return data.name.indexOf(value) !== -1;
}
},
}
</script>
<style>
.show-hide {
width: 100%;
position: relative;
}
.buttonList {
position: absolute;
right: 8px;
display: none;
}
.more {
font-size: 16px;
}
.more_none {
display: none;
}
.buttonList span {
padding: 0px 3px;
}
.node_input {
width: 80px;
}
.inputsty {
color: #000;
}
.show-hide:hover :nth-child(2) {
display: inline-block !important;
}
.el-dropdown-menu__item {
padding: 0px 14px;
cursor: pointer;
}
.el-dropdown-menu__item:not(.is-disabled):focus {
background-color: rgb(145, 156, 185, 0.1);
}
.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
color: #fff;
}
</style>