zTree的使用踩坑记录(编辑、新增)
9374 2023/5/26 zTree
原文地址 (opens new window) 最近做了一个功能,在vue中使用到了zTree,要求实现树节点的新增和编辑,即鼠标移到节点上的时候显示出这两个按钮,点编辑的时候节点会变成输入框可直接输入,点新增的时候会在该节点的子节点中新增一个节点,并显示为可编辑状态。
做的过程中踩了不少坑,记录下。
附官网API地址 (opens new window)(直接看API比在网上找乱七八糟的代码有用多了)
# 首先是先在main.js引入ztree插件
记住,如果有用到ztree自带的编辑或删除,一定要记得引入 jquery.ztree.exedit.min;同时,ztree没有添加节点的按钮,需要我们自己创建
# 页面
html部分只需要:
<ul id="resourceTree" class="ztree"></ul>
1
# 代码
# 配置
setting: {
//在这里配置 添加按钮(自定义)
view: {
addHoverDom: this.addHoverDom, //当鼠标移动到节点上时,显示用户自定义控件
removeHoverDom: this.removeHoverDom, //离开节点时的操作
},
//在这里配置编辑或删除按钮,删除按钮没有写,有需要的话移步官网API~
edit:{
enable: true,
editNameSelectAll: true,
showRemoveBtn: false, //删除按钮不显示
showRenameBtn: this.showRenameBtn, //编辑按钮
renameTitle: '编辑' //编辑按钮hover上去后显示的title提示
},
data: {
simpleData: {
enable: true,
idKey: "bkid", //配合后端返回的字段名称填写,这里是节点id
pIdKey: "bkpid" //这里是父节点id
},
key: {
name: "bkname" //配合后端返回的字段名称填写,展示的节点名称
}
},
callback: {
onClick: this.selectChange, //节点选中事件
beforeRename: this.beforeRename, //用于捕获更新节点名称之前,这里可以用来写判断节点名称不为空
onRename: this.onRename //更新节点名称事件
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 加载树的数据
getResourceTree(treeNode){
var thiz = this;
this.$store.dispatch('axios_req',
{
type:'post',
url: 'tree.do',
async: false,
data : {}, //直接传入data
success : function(res) {
thiz.resourceTree = res.data.data;
thiz.initTree();
//这里是新增完节点后,刷新tree,定位到刚刚新增的那个节点,并直接进入编辑状态,这里的代码视实际操作情况写
if(treeNode){
var zTree = $.fn.zTree.getZTreeObj("resourceTree");
var node = zTree.getNodesByParam('bkid', treeNode.bkid)
zTree.expandNode(node[0], true, false);//展开父节点
zTree.selectNode(node[0].children[0]);//选中当前节点
zTree.editName(node[0].children[0]);//进入编辑状态
}
},
fail : function(err) {
console.log('out fail : ' + err);
}
}
)
},
initTree(){
//非异步加载模式下,无子节点的父节点设置 open=true 后,可显示为展开状态,但异步加载模式下不会生效
$.fn.zTree.init($("#resourceTree"), this.setting, this.resourceTree);
var treeObj = $.fn.zTree.getZTreeObj("resourceTree");
var nodes = treeObj.getNodes();
for (var i = 0; i < 2; i++) { //设置节点展开
treeObj.expandNode(nodes[i], true, false, true);
}
//treeObj.expandAll(false);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 编辑节点
//判断节点名称不能为空
beforeRename(treeId, treeNode, newName) {
var thiz = this;
if (newName.trim().length == 0) {
$.fn.zTree.getZTreeObj("resourceTree").cancelEditName();
thiz.$Message.info('节点名称不能为空');
return false;
}
return true;
},
//ztree编辑事件
onRename(treeId, treeNode, newName){
var thiz = this;
thiz.$store.dispatch('axios_req',
{
type:'post',
url: 'edit.do',
data : {
}, //直接传入data
success : function(res) {
},
fail : function(err) {
console.log('out fail : ' + err);
}
}
)
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 添加节点
//ztree新增节点
addHoverDom(treeId, treeNode){
var thiz = this;
var sObj = $("#" + treeNode.tId + "_span");
if (treeNode.editNameFlag || $("#addBtn_"+treeNode.tId).length>0) return;
var addStr = "<span class='button add' id='addBtn_" + treeNode.tId + "' title='新增' οnfοcus='this.blur();'></span>"; //定义添加按钮
sObj.after(addStr); //加载添加按钮
var btn = $("#addBtn_"+treeNode.tId);
//绑定添加事件,并定义添加操作
if (btn) btn.bind("click", function(event){
event.stopPropagation();
var zTree = $.fn.zTree.getZTreeObj("resourceTree");
//将新节点添加到数据库中
var name = '';
if(treeNode.children){
name = '默认名称' + (treeNode.children.length + 1)
}else{
name = '默认名称1';
}
thiz.$store.dispatch('axios_req',
{
type:'post',
url: 'add.do',
data : {
}, //直接传入data
success : function(res) {
if(res.data.success){
//刷新树
thiz.getResourceTree(treeNode);
}
},
fail : function(err) {
console.log('out fail : ' + err);
}
}
)
});
},
//ztree移除新增节点
removeHoverDom(treeId, treeNode){
$("#addBtn_"+treeNode.tId).unbind().remove();
},
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# 节点选中
//ztree选中事件
selectChange(event, treeId, treeNode){
var thiz = this;
thiz.rowData = treeNode;
thiz.controlList = true;
},
1
2
3
4
5
6
7
2
3
4
5
6
7
# 功能到这个差不多就结束了,另外树的样式修改我选择了自己写css直接覆盖,可参考
//less
@treeCloseIcon: url('../../assets/dispatch/tree_close_blue.png');
@treeOpenIcon: url('../../assets/dispatch/tree_open_blue.png');
@treeFileIcon: url('../../assets/dispatch/tree_file_blue.png');
@treeFileIconHov: url('../../assets/dispatch/tree_file_hov.png');
@startP: #677294;
/* 隐藏原始的文件夹图标 */
.ztree li span.button.ico_close{
display: none;
}
.ztree li span.button.ico_open{
display: none;
}
/* 节点名称样式 */
.ztree .node_name{
color: @startP;
margin: 4px 1px;
padding: 0 4px;
height: 20px;
line-height: 20px;
display: inline-block;
}
/* 编辑时候的输入框 */
.ztree .node_name input{
width: 100%;
height: 100%;
}
/* 节点展开 前面的加号图标修改 */
.ztree li span.button.center_close,
.ztree li span.button.root_close,
.ztree li span.button.bottom_close{
background: @treeCloseIcon !important;
background-size: 100% 100% !important;
width: 16px;
height: 16px;
margin-top: 6px;
}
/* 节点关闭 前面的减号图标修改 */
.ztree li span.button.center_open,
.ztree li span.button.root_open,
.ztree li span.button.bottom_open{
background: @treeOpenIcon !important;
background-size: 100% 100% !important;
width: 16px;
height: 16px;
margin-top: 6px;
}
/* 节点行高拉大 */
.ztree li a{
height: 28px;
line-height: 28px;
}
/* 最后一级的节点图标修改 */
.ztree li span.button.ico_docu{
background: @treeFileIcon !important;
display: inline-block;
vertical-align: middle;
margin-top: -6px;
}
/* 最后一级的节点图标 前面的虚线位置修改(因为行高被我改大了...) */
.ztree li span.button.switch{
display: inline-block;
vertical-align: middle;
margin-top: 5px;
}
/* 节点选中样式 */
.ztree li a.curSelectedNode{
background-color: transparent;
border: 1px solid transparent;
opacity: 1;
}
.ztree li a.curSelectedNode .node_name{
background-color: #008FFF;
border: none;
color: #fff;
}
.ztree li a.curSelectedNode .ico_docu{
background: @treeFileIconHov !important;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89