最近做了一個功能,在vue中使用到了zTree,要求實現樹節點的新增和編輯,即鼠標移到節點上的時候顯示出這兩個按鈕,點編輯的時候節點會變成輸入框可直接輸入,點新增的時候會在該節點的子節點中新增一個節點,並顯示爲可編輯狀態。
做的過程中踩了不少坑,記錄下。
附官網API地址(直接看API比在網上找亂七八糟的代碼有用多了)
首先是先在main.js引入ztree插件
記住,如果有用到ztree自帶的編輯或刪除,一定要記得引入 jquery.ztree.exedit.min;同時,ztree沒有添加節點的按鈕,需要我們自己創建
html部分只需要:
<ul id="resourceTree" class="ztree"></ul>
接下來,在data裏面設一下樹的配置
配置:
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 //更新節點名稱事件
}
}
開始貼代碼
加載樹的數據:
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);
}
編輯節點:
//判斷節點名稱不能爲空
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);
}
}
)
},
添加節點:
//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();
},
節點選中:
//ztree選中事件
selectChange(event, treeId, treeNode){
var thiz = this;
thiz.rowData = treeNode;
thiz.controlList = true;
},
功能到這個差不多就結束了,另外樹的樣式修改我選擇了自己寫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;
}
展示效果如下:
點編輯按鈕進入編輯狀態:
END