先来一张效果图:
1.z-tree插件下载地址http://www.treejs.cn/v3/main.php#_zTreeInfo
2.下载完成后将插件放到项目里在mian.js里面引入即可
//main.js中引入
import './plugins/zTree/jquery.ztree.all.js'
import './plugins/zTree/jquery.ztree.core.js'
import './plugins/zTree/jquery.ztree.excheck.js'
import './plugins/zTree/jquery.ztree.exedit.js'
import './plugins/zTree/jquery.ztree.exhide.js'
3.ztree组件内部代码
<template>
<div id="areaTree">
<div class="addnode" v-if="addtype!=false"></div>
<div class="boxtitle">
<el-input
id="key"
size="mini"
placeholder="请输入内容"
suffix-icon="el-icon-search"
v-model="inputval">
</el-input>
<el-button type="primary" size="mini" title="刷新" icon="el-icon-refresh" @click="shauxin"></el-button>
<el-button type="primary" size="mini" v-if="addtype===false?addtype:addtype1" title="添加根目录" icon="el-icon-plus" @click="addzTreeOne"></el-button>
</div>
<div class="tree-box">
<div class="zTreeDemoBackground left">
<ul id="treeDemo" class="ztree"></ul>
</div>
</div>
</div>
</template>
<script>
// import fuzzysearch from "@/plugins/fuzzysearch.js";
export default {
name: 'ztree',
data () {
return {
inputval: '',
prid: '',
ztreedata: '',
addtype1: true,
addchild1: true
}
},
props: ['treedata','addtype','addchild'],
components: {
},
watch: {
immediate: true,
treedata(newval, oldval) {
this.ztreedata = newval;
this.szTree();
}
},
created() {
},
mounted() {
this.szTree();
},
methods: {
shauxin() {
this.$emit('shuaxin')
},
szTree: function(iname) {
var setting = {
view: {
addHoverDom: this.addtype===false||this.addchild===false?false:this.addHoverDom,
removeHoverDom: this.removeHoverDom,
selectedMulti: false,
addDiyDom: this.addDiyDom,
// showIcon: false,
showLine: true,
},
edit: {
enable: this.addtype===false?false:true,
// showRenameBtn: true,
renameTitle: "编辑目录名称",
removeTitle: "删除目录",
drag: {
prev: this.canPrev,
next: this.canNext,
inner: true
}
},
callback: {
onClick: this.zTreeOnClick,
beforeDrag: this.beforeDrag,
beforeDrop: this.beforeDrop, //用于捕获节点拖拽操作结束之前的事件回调函数
onNodeCreated: this.zTreeOnNodeCreated, //改图标
beforeEditName: this.zTreeBeforeRename, //编辑节点
beforeRemove: this.zTreeBeforeRemove //删除节点
},
data: {
key:{
name:"catalogName"
},
simpleData: {
enable: true,
idKey : "dataSourceGroupId",
pIdKey : "parentDSource",
rootPId : null
}
},
};
$.fn.zTree.init($("#treeDemo"), setting, this.ztreedata);
this.fuzzySearch('treeDemo', '#key', null, true); //初始化模糊搜索方法
},
// 划过显示添加节点
addHoverDom: function(treeId, treeNode) {
var _this = this;
// console.log(treeNode)
// if(treeNode.parentDSource!=null) {
// $("#" + treeId + " .button.edit").hide();
// $("#" + treeId + " .button.remove").hide();
// }
// 判断是数据源子节点隐藏增修改图标
if (treeNode.type == 0) {
$("#" + treeId + " .button.add").hide(); //隐藏添加图标
$("#" + treeId + " .button.edit").hide();
$("#" + treeId + " .button.remove").hide();
} else {
//添加目录
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='添加下级目录' onfocus='this.blur();'></span>";
sObj.after(addStr); //注释下级目录添加
var btn = $("#addBtn_" + treeNode.tId);
$('.ztree li span.button.add').css({
'margin-left': '2px',
'margin-right': '-1px',
'background-position': '-144px 0',
'vertical-align': 'top',
})
if (btn) btn.bind("click", function() {
_this.$emit('addtreeNode', {'treeNode': treeNode})
});
}
},
// 滑动覆盖移除
removeHoverDom(treeId, treeNode) {
$("#addBtn_" + treeNode.tId).unbind().remove();
},
//自定义显示内容,字数截取
addDiyDom: function(treeId, treeNode) {
var spantxt = $("#" + treeNode.tId + "_span").html();
},
//禁止拖拽到顶级节点前面的操作
canPrev: function(treeId, nodes, targetNode) {
console.log("targetNode", targetNode);
var pNode = targetNode.getParentNode();
if (pNode && pNode.dropInner === false) {
return false;
}
if (!targetNode.parentDSource && nodes[0].type == 0) {
return false;
}
return true;
},
//禁止拖拽到根节点后面的操作
canNext: function(treeId, nodes, targetNode) {
if (!targetNode.parentDSource && nodes[0].type == 0) {
return false;
}
return true;
},
//拖拽之前判断是否可拖拽
beforeDrag: function(treeId, treeNodes) {
return false;
// return true;
},
//拖拽结束之后
beforeDrop: function(treeId, treeNodes, targetNode, moveType) {
console.log(targetNode);
this.prid = treeNodes[0].parentDSource ? treeNodes[0].parentDSource : "";
if (targetNode == null)
return false;
var newPrid = targetNode.dataSourceGroupId
if (targetNode.type == 0) {
return false;
}
var msid = treeNodes[0].dataSourceGroupId;
var ypid = this.prid; //原来的父级ID
var xpid = newPrid; //现在的父级ID
var type = treeNodes[0].type; //类型,0是数据源,1是目录
if (this.prid == newPrid) {
xpid = "";
}
//修改原目录图标
var zTree_Menu = $.fn.zTree.getZTreeObj("treeDemo");
var node = zTree_Menu.getNodeByParam("id", ypid);
},
// 编辑节点
zTreeBeforeRename: function(treeId, treeNode, newName, isCancel) {
this.$emit('zTreeBeforeRename',{'treeNode':treeNode});
return false;
},
//删除组
zTreeBeforeRemove: function(treeId, treeNode) {
this.$emit('removeTreeNode',{'treeId': treeId, 'treeNode': treeNode})
return false;
},
//点击单个节点
zTreeOnClick: function(event, treeId, treeNode) {
this.$emit('zTreeOnClick',{'treeNode':treeNode});
},
// 添加根目录
addzTreeOne: function(){
this.$emit('addzTreeOne');
},
// 模糊查询方法
fuzzySearch(zTreeId, searchField, isHighLight, isExpand){
var zTreeObj = $.fn.zTree.getZTreeObj(zTreeId);//get the ztree object by ztree id
if(!zTreeObj){
alert("fail to get ztree object");
}
var nameKey = zTreeObj.setting.data.key.name; //get the key of the node name
isHighLight = isHighLight===false?false:true;//default true, only use false to disable highlight
isExpand = isExpand?true:false; // not to expand in default
zTreeObj.setting.view.nameIsHTML = isHighLight; //allow use html in node name for highlight use
var metaChar = '[\\[\\]\\\\\^\\$\\.\\|\\?\\*\\+\\(\\)]'; //js meta characters
var rexMeta = new RegExp(metaChar, 'gi');//regular expression to match meta characters
// keywords filter function
function ztreeFilter(zTreeObj,_keywords,callBackFunc) {
if(!_keywords){
_keywords =''; //default blank for _keywords
}
// function to find the matching node
function filterFunc(node) {
if(node && node.oldname && node.oldname.length>0){
node[nameKey] = node.oldname; //recover oldname of the node if exist
}
zTreeObj.updateNode(node); //update node to for modifications take effect
if (_keywords.length == 0) {
//return true to show all nodes if the keyword is blank
zTreeObj.showNode(node);
zTreeObj.expandNode(node,isExpand);
return true;
}
//transform node name and keywords to lowercase
if (node[nameKey] && node[nameKey].toLowerCase().indexOf(_keywords.toLowerCase())!=-1) {
if(isHighLight){ //highlight process
//a new variable 'newKeywords' created to store the keywords information
//keep the parameter '_keywords' as initial and it will be used in next node
//process the meta characters in _keywords thus the RegExp can be correctly used in str.replace
var newKeywords = _keywords.replace(rexMeta,function(matchStr){
//add escape character before meta characters
return '\\' + matchStr;
});
node.oldname = node[nameKey]; //store the old name
var rexGlobal = new RegExp(newKeywords, 'gi');//'g' for global,'i' for ignore case
//use replace(RegExp,replacement) since replace(/substr/g,replacement) cannot be used here
node[nameKey] = node.oldname.replace(rexGlobal, function(originalText){
//highlight the matching words in node name
var highLightText =
'<span style="color: whitesmoke;background-color: darkred;">'
+ originalText
+'</span>';
return highLightText;
});
zTreeObj.updateNode(node); //update node for modifications take effect
}
zTreeObj.showNode(node);//show node with matching keywords
return true; //return true and show this node
}
zTreeObj.hideNode(node); // hide node that not matched
return false; //return false for node not matched
}
var nodesShow = zTreeObj.getNodesByFilter(filterFunc); //get all nodes that would be shown
processShowNodes(nodesShow, _keywords);//nodes should be reprocessed to show correctly
}
/**
* reprocess of nodes before showing
*/
function processShowNodes(nodesShow,_keywords){
if(nodesShow && nodesShow.length>0){
//process the ancient nodes if _keywords is not blank
if(_keywords.length>0){
$.each(nodesShow, function(n,obj){
var pathOfOne = obj.getPath();//get all the ancient nodes including current node
if(pathOfOne && pathOfOne.length>0){
//i < pathOfOne.length-1 process every node in path except self
for(var i=0;i<pathOfOne.length-1;i++){
zTreeObj.showNode(pathOfOne[i]); //show node
zTreeObj.expandNode(pathOfOne[i],true); //expand node
}
}
});
}else{ //show all nodes when _keywords is blank and expand the root nodes
var rootNodes = zTreeObj.getNodesByParam('level','0');//get all root nodes
$.each(rootNodes,function(n,obj){
zTreeObj.expandNode(obj,true); //expand all root nodes
});
}
}
}
//listen to change in input element
$(searchField).bind('input propertychange', function() {
var _keywords = $(this).val();
searchNodeLazy(_keywords); //call lazy load
});
var timeoutId = null;
var lastKeyword = '';
// excute lazy load once after input change, the last pending task will be cancled
function searchNodeLazy(_keywords) {
if (timeoutId) {
//clear pending task
clearTimeout(timeoutId);
}
timeoutId = setTimeout(function() {
if (lastKeyword === _keywords) {
return;
}
ztreeFilter(zTreeObj,_keywords); //lazy load ztreeFilter function
// $(searchField).focus();//focus input field again after filtering
lastKeyword = _keywords;
}, 500);
}
}
},
}
</script>
<style lang='scss' scoped>
@import '../plugins/zTree/css/zTreeStyle/zTreeStyle.css';
.ztree {
padding: 0;
max-height: 28rem;
overflow: auto;
&::-webkit-scrollbar-track-piece { //滚动条凹槽的颜色,还可以设置边框属性
background-color:#f8f8f8;
}
&::-webkit-scrollbar {//滚动条的宽度
width:6px;
height:6px;
}
&::-webkit-scrollbar-thumb {//滚动条的设置
background-color:#dddddd;
background-clip:padding-box;
min-height:28px;
}
&::-webkit-scrollbar-thumb:hover {
background-color:#bbb;
}
}
.tree-box {
padding: 0 .8rem;
}
#areaTree{
// min-height: 30rem;
margin-bottom: 2px;
padding-bottom: 1rem;
.addnode {
display: flex;
justify-content: center;
padding: .4rem 0;
// border-bottom: 1px solid #d9e2eb;
}
.boxtitle{
display: flex;
justify-content: space-around;
margin: .5rem .8rem;
button {
margin-left: 0.5rem;
}
}
}
</style>
4.组件使用
<ztree :treedata='treedata' :addtype='addtype' v-on:addtreeNode="addtreeNode" v-on:zTreeBeforeRename="zTreeBeforeRename" v-on:zTreeOnClick="zTreeOnClick" v-on:addzTreeOne="addzTreeOne" v-on:shuaxin="shauxin" v-on:removeTreeNode="removeTreeNode"></ztree>
treedata:后台返回的tree数据格式
"data":[
{
"catalogName":"文件夹1", //节点名字
"dataSourceGroupId":"111", //节点ID
"parentDSource":"NULL", //父级ID
"type":"1" //自定义属性: 1-文件夹 0-文件
},
{
"catalogName":"文件2", //节点名字
"dataSourceGroupId":"rrr", //节点ID
"parentDSource":"222", //父级ID
"type":"0" //自定义属性: 1-文件夹 0-文件
},
],
addtype: 添加根节点的显示隐藏
addtreeNode: 添加子节点的显示隐藏
zTreeBeforeRename: 编辑节点回调函数
// 编辑节点
zTreeBeforeRename(obj) {
this.nodeName=obj.treeNode.catalogName;
},
zTreeOnClick:点击单个节点回调
// 点击单个节点
zTreeOnClick(obj) {
if(obj.treeNode.type==1){
//点击的是文件夹
}
if(obj.treeNode.type==0){
//点击的是文件
}
},
addzTreeOne:添加根目录回调
// 添加根节点
addzTreeOne() {
},
shauxin:刷新树结构
// 刷新树结构
shauxin() {
//重新获取tree数据
},
removeTreeNode:删除节点
//移除节点
removeTreeNode(obj) {
}
在添加和删除之后如果直接调用后台接口刷新树结构会导致树结构的展开、选中等操作初始化,可以使用下面代码对树结构进行跟新
添加节点:
//发送添加节点请求....
if(res.status == 200) {
//请求成功后
var treeObj = $.fn.zTree.getZTreeObj("treeDemo");
var parentZNode = treeObj.getSelectedNodes(); //获取父节点
var newNode = {
catalogName: this.collectionName,//节点名字
dataSourceGroupId: res.data.id,//节点id
parentDSource: this.nodeid, //父级id,可以在点击单个节点时存下
type: 1, //自定义属性
icon: icojq //图标
iconOpen: files, //展开时图标
iconClose: file, //闭合时图标
};
newNode.nodeFlg = 1; // 可以自定义节点标识
newNode = treeObj.addNodes(parentZNode[0], newNode, true);
}
编辑节点:
//发送修改节点请求...
if(res.status == 200) {
//请求成功
var zTree = $.fn.zTree.getZTreeObj("treeDemo");
this.nodeobj.treeNode.catalogName = this.ruleForm.baseNodeName;
zTree.updateNode(this.nodeobj.treeNode);
this.conName = '';
}
删除节点:
//发送删除请求...
if(res.status == 200) {
//请求成功
var treeObj = $.fn.zTree.getZTreeObj(obj.treeId);
var parentZNode = treeObj.getNodesByParam("dataSourceGroupId", obj.treeNode.dataSourceGroupId, null);
treeObj.removeNode(parentZNode[0]);
}
图标根据项目图片位置引入即可:
import icojq from "@/assets/img/23.png"
import file from "@/assets/img/21.png"
import files from "@/assets/img/22.png"