上一次写ztree的使用,还是在2年前,如今我已经是个成熟的ztree的使用者了,今天我们再来详细的介绍一下,如何在vue中使用ztree;
先来看下我写好的效果
需要解决的问题:
1.左侧导航栏有滚动条,因为overflow:hidden属性,右键节点出现菜单不能被遮住
2.点击展开节点,默认一次要展开5个层级节点(难点)
3.对于文件名称超长的文本,需要显示...,对只有超长的文本鼠标hover的时候出现tips提示(有技巧)
4。对于不存在接口当中的数据,但是我页面又需要展示,也就是节点的操作(熟悉ztree的都知道,节点操作其实是最简单的,只要按照ztree的规则组装节点,什么复制节点,移除节点,添加节点巴拉巴拉都是小问题);我的右键菜单中,大家可以看到有复制/移动功能,且我页面上是有三颗没有任何关联的树,当我使用复制/移动功能将某一个节点移动到其他树上的时候,需要将当前树的节点移除,而目标树新增一个节点(其实实现真的超级简单了)
5.我们设计原本给我提了一个需求,要求ztree选中节点的背景色要包含展开和收缩的小图标,我以为很简单,事实也很简单,不过要熟悉官网
6.每个层级溢出的文本长度不一致(图3),就是每一个层级溢出隐藏的长度需要在可视范围,这个应该很少用到吧,这里就不讲了
7.文件节点的新建和修改,都是ztree的onrename 输入框失焦事件,如何区分修改和新建,利用ztree提供的dataFilter方法,可以将接口返回的数据自定义添加自己所需要的属性
图1
图2
data() {
return {
treeObj: '',
settings: {
data: {
simpleData: {
enable: false,//看接口返回的数据是简单数据类型还是标签的json数据
},
key: {
name: 'name', //节点显示名称后台所定义的字段
isParent: 'hasChildren' //接口数据定义父子关系的字段
}
},
callback: {
onClick:this.zTreeOnClick,
onRename: this.zTreeOnRename,//输入框失焦事件
// beforeEditName: this.zTreeBeforeEditName,//重命名之前的事件
beforeRename:this.ztreeBeforeRename,//input输入框失焦或者按住enter的事件
onRightClick: this.zTreeOnRightClick,//右键点击出现菜单
onNodeCreated: this.zTreeOnNodeCreated,//
beforeAsync: this.beforeAsync,//异步请求前回调
onAsyncSuccess: this.onAsyncSuccess,//异步请求成功之后的回调
onAsyncError: this.onAsyncError,//异步失败的回调
beforeExpand: this.zTreeBeforeExpand, //节点展开前的回调
onCollapse: this.zTreeOnCollapse, //节点收起的回调
},
//异步节点所触发的接口,如果是同步则不需要,拿到数据直接渲染
async: {
enable: true,
contentType: "application/json",
type: 'post',
url: "/cross/resourcemanagerservice/api/resource/container/get",
dataType: 'json',
// autoParam: ["id=''"],
//接口所需要的参数
otherParam:{"needParent":false,"recursively":false,"userId":this.userId,"tenantId":this.tenantId,parentId: this.$route.name == 'assetlibrary' ? 'LIBRARY_PUBLIC_DOMAIN_' : '_PUBLIC_DOMAIN_'},
dataFilter: function (treeId, parentNode, data) {
data.containerList.forEach(node => {
//这里添加节点是重新命名还是新建的标识
node.isEdit = false;
});
return data.containerList;
}
},
edit: {
enable: true,
showRemoveBtn: false,
showRenameBtn: false,
drag:{
isCopy:false,
isMove:false
},
editNameSelectAll: true
},
view: {
addDiyDom:this.addDiyDom, //自定义页面展现树节点的结构
addHoverDom: this.addHoverDom,//鼠标hover节点的时候的钩子函数
removeHoverDom: this.removeHoverDom, //鼠标移除节点所触发的钩子函数,与addhoverdom配套使用
showLine:false,//是否显示节点的链接线
showTitle:false,//是否显示节点的title属性
fontCss:{'color':'#333'} //设置节点的字体样式
}
},
}
},
在mounted中初始化树形结构
mounted() {
// ztree-public为你装载树型结构的dom的名称
this.treeObj = $.fn.zTree.init($("#ztree-public"), this.settings);
},
问题2,5的解决方法:背景色包含整个节点,包含收缩和展开的小图标,文件夹名称超长显示tips
addDiyDom(treeId, treeNode){
// 此操作是为了将节点的展开和收起按钮包在背景色当中
var switchObj = $("#" + treeNode.tId + "_switch"), //节点的展开dom
icoObj = $("#" + treeNode.tId + "_ico"); //节点图标文件夹
switchObj.remove();
icoObj.before(switchObj); //再每个ico前面插入节点
// 修改node_name的结构,这里是文件夹名称超长,鼠标hover超长文本的时候核心方法,同样也是修改ztree渲染节点信息的结构来实现
var nodeName = $("#" + treeNode.tId + "_span")
var newDom = $("<div class='node-name-box' id='node_name-box" + treeNode.tId
+ "'></div>");
nodeName.remove()
icoObj.after(newDom)
newDom.append(nodeName)
},
问题1的解决方法:
其实在vue3中,这很容易实现,vue3的新特性teleport组件可以将dom结构渲染在任何你想要的位置,但是我是vue2,所以自己写了个组件,去模拟teleport组件
<script>
export default {
// 模拟vue3的新特性
name: 'teleport',
props: {
/* 移动至哪个标签内,最好使用id */
to: {
type: String,
required: true
}
},
mounted() {
document.querySelector(this.to).appendChild(this.$el)
},
destroyed() {
document.querySelector(this.to).removeChild(this.$el)
},
render() {
return <div>{this.$scopedSlots.default()}</div>
}
}
</script>
使用方式如下:
<teleport to="body">
<div id="rMenu">
<ul>
<li id="m_del" @click="removeTreeNode();">删除</li>
<li id="m_check" @click="updateTreeNode();>重命名</li>
<li id="m_copy" @click="copypasteTreeNode();">复制/移动到...</li>
<li id="m_setroles" @click="setaclTreeNode();">设置权限</li>
<li id="m_lifecycle" @click="setlifeTreeNode();">设置生命周期</li>
<li id="m_space" @click="dialogSpace = true">设置空间配额</li>
</ul>
</div>
<!-- 当节点名称过长,鼠标hover显示tips -->
<div id="rMenu-name">
{{hoverDomName}}
<span class="box-list-arrow"></span>
</div>
</teleport>
问题4,很简单,看官网,节点的操作方法,非同一颗树之间节点的复制和粘贴,其实给每个树绑定ref属性,然后去调用每个树的方法就行了,类似这样
我懒,就写这么多吧
问题2:我觉得除了我们产品,应该没有哪个产品会提这么变态的需求吧,也不想讲了,有需要的可以提供思路