在 vue 项目中使用ztree插件,实现增删改查功能,并对增删改查功能实现二次封装。
如何在vue项目使用ztree
- 下载ztree
ztree官网下载ztree插件,并将对应的 js 和 css 文件放到vue项目中。
- 引入
在vue项目中的main.js
入口文件引入
import $ from 'jquery';
import '@/assets/js/ztree/zTreeStyle/zTreeStyle.css';
import './assets/js/ztree/jquery.ztree.core.js';
import './assets/js/ztree/jquery.ztree.excheck.js';
import './assets/js/ztree/jquery.ztree.exedit.js';
- 配置
在vue项目的 vue.config.js
中进行配置。
module.exports = {
configureWebpack: {
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
'windows.jQuery': 'jquery'
})
]
},
}
- 使用
完成以上几步就可以使用ztree了。
实现结果
ztree组件
html部分
<template>
<div class="objZtree">
<div class="split-body">
<div class="split-content">
<ul id="objTree" class="ztree" style="min-height: 500px"></ul>
</div>
</div>
</div>
</template>
js部分
<script>
// import $ from 'jquery';
import './iconfont.css';
export default {
props: {
searchedData: {
type: Array
}
},
data() {
return {
setting: {
view: {
// 显示图标
showIcon: true,
// 鼠标移入节点时触发
addHoverDom: this.addHoverDom,
// 鼠标移除节点时触发
removeHoverDom: this.removeHoverDom,
// 设置节点字体样式
fontCss: {
margin: '6px'
}
},
edit: {
enable: true,
// 是否显示默认的删除按钮
showRemoveBtn: false,
showRenameBtn: false
},
callback: {
// ztree默认删除按钮-删除之前调用
// beforeRemove: this.beforeRemove
// 点击展开按钮发送请求-发送请求之前调用
beforeAsync: this.beforeAsync,
// 异步请求成功调用
onAsyncSuccess: this.zTreeOnAsyncSuccess,
// 点击节点时调用-本组件用于查看节点内容
onClick: this.zTreeOnClick
},
data: {
// 用于指定节点显示名称的数据字段名
key: {
name: 'name'
}
},
async: {
// 设置异步请求
enable: true,
// 请求的 url 地址
url: function (treeId, treeNode) {
// console.log('异步请求', treeId, treeNode); // 得到当前节点的信息
return './index.vue';
},
type: 'GET'
}
},
// 初始化节点数据
initalNode: [],
currentTreeId: '',
currentTreeNode: []
};
},
created() {
this.getTreeCate();
},
methods: {
// 初始化 ztree 的函数
loadObjTree() {
$.fn.zTree.init($('#objTree'), this.setting, this.initalNode);
},
beforeAsync(treeId, treeNode) {
console.log('异步请求发送之前触发', treeId, treeNode);
},
zTreeOnAsyncSuccess(event, treeId, treeNode, msg) {
console.log('异步请求成功回调函数执行', event, treeId, treeNode, msg);
// ztree 中添加节点
// zTree.addNodes(treeNode, msg);
},
zTreeOnClick(event, treeId, treeNode) {
// 点击某一个节点时触发的函数
let zTree = $.fn.zTree.getZTreeObj(treeId);
let selectedNodes = zTree.getSelectedNodes(true); // 得到点击的节点(选中的节点)
this.$emit('changeViewVisible', selectedNodes[0], selectedNodes[0].level);
},
addHoverDom(treeId, treeNode) {
this.currentTreeId = treeId;
this.currentTreeNode = treeNode;
var aObj = $('#' + treeNode.tId + '_span');
if ($('#diyBtnGroup').length > 0) return;
let editStr;
// 自定义 增删改 图标样式
if (treeNode.level === 0) {
editStr = `<span id='diyBtnGroup'>
<i class="iconfont icon-tianjia" style="color: #1296db;margin-left: 5px;" id='diyBtn_${treeNode.id}_add' οnClick='this.blur();'></i>
</span>`;
} else if (treeNode.level === 1) {
editStr = `<span id='diyBtnGroup'>
<i class="iconfont icon-bianji" style="color: #1296db;margin-left: 5px;" id='diyBtn_${treeNode.id}_modify' οnClick='this.blur();'></i>
<i class="iconfont icon-cangpeitubiao_shanchu" style="color: #1296db;margin-left: 5px;" id='diyBtn_${treeNode.id}_delete' οnClick='this.blur();'></i>
</span>`;
}
aObj.append(editStr); // 在每个节点后添加自定义按钮组
var btnDelete = $('#diyBtn_' + treeNode.id + '_delete');
var btnAdd = $('#diyBtn_' + treeNode.id + '_add');
var btnModify = $('#diyBtn_' + treeNode.id + '_modify');
if (btnDelete) {
btnDelete.bind('click', (e) => {
// 触发父组件的方法,使删除对话框显示
this.$emit('delConfirm');
});
}
if (btnAdd) {
btnAdd.bind('click', (e) => {
e.stopPropagation();
this.$emit('changeAddFormVisible', treeNode);
});
}
if (btnModify) {
btnModify.bind('click', (e) => {
e.stopPropagation();
this.$emit('changeModifyVisible', treeNode, true);
});
}
},
// 删除之前调用的逻辑
// beforeRemove(e) {
// console.log(e);
// alert('确定要删除吗');
// },
// 子组件定义删除节点的方法,通过在父组件的删除对话框中点击确定按钮,调用该方法删除对应的节点--this.$refs.ZtreeRef.delNode();
delNode() {
var treeObj = $.fn.zTree.getZTreeObj(this.currentTreeId);
var nodes = treeObj.getSelectedNodes();
// 发送请求删除节点
this.$http.delete('/dg/api/v1/datasources/' + nodes[0].id).then((res) => {
if (res.code === 0) {
this.$Message.success('删除分类成功');
this.getTreeCate();
} else {
this.$Message.error('删除分类失败');
}
});
},
addNode(newAddInfo) {
console.log('新增信息', newAddInfo);
let newAddDbParams = {
...newAddInfo
};
console.log('newAddDbParams', newAddDbParams);
this.$http.post('/dg/api/v1/datasources', newAddDbParams).then((res) => {
console.log('新增节点', res);
if (res.code === 0) {
this.$Message.success('新增节点成功!');
this.$emit('handleReset');
// 采用重新发送请求获取数据的方式添加节点
this.getTreeCate();
} else {
this.$Message.error({
content: res.msg,
duration: 10,
closable: true
});
}
});
// var add = treeObj.addNodes(nodes[0], newAddNodeParams); // 在父节点下添加新节点,parentNode 为null使就是添加父节点
// console.log('新增节点后的返回值', add); // 以数组的方式返回新增的节点
},
// 修改节点信息
modifyNode(updatedinfo) {
console.log('修改后的信息', updatedinfo, this.currentTreeNode);
// 需要发送给后台的数据参数
let modifyDbParams = {
...updatedinfo,
modifyDepartment: '',
modifyTime: '',
modifyUser: ''
};
console.log('修改传参', modifyDbParams);
this.$http.put('/dg/api/v1/datasources', modifyDbParams).then((res) => {
if (res.code === 0) {
this.$Message.success('修改节点成功!');
this.getTreeCate();
// 影藏修改框
this.$emit('changeModifyVisible', [], false);
} else {
this.$Message.error('修改节点失败');
}
});
},
// 鼠标离开当前节点的逻辑
removeHoverDom: (treeId, treeNode) => {
// 为了方便删除整个 button 组,上面我用 #diyBtnGroup 这个包了起来,这里直接删除外层即可,不用挨个找了。
$('#diyBtnGroup').unbind().remove();
},
// 获取分类数据
getTreeCate() {
// 发送请求--获取ztree的初始数据
this.$http.get('/dg/api/v1/datasources/type').then((res) => {
if (res.code === 0) {
// 添加节点前的图标
this.initalNode = this.addIcon(res.data);
console.log('新增图标', this.addIcon(res.data));
localStorage.setItem('initDbData', JSON.stringify(res.data));
// 经过测试:执行初始化ztree函数,放到mounted种不行
this.loadObjTree();
}
});
},
addIcon(treeNodeData) {
return treeNodeData.map((item) => {
item.icon = 'https://s3.ax1x.com/2021/01/09/sMM9MQ.png';
item.iconSkin = 'icon1';
// 为二级节点添加图标
if (item.children.length > 0) {
item.children.forEach((item1) => {
item1.icon = 'https://s3.ax1x.com/2021/01/09/sM1JJ0.png';
item1.iconSkin = 'icon2';
});
}
return item;
});
}
},
mounted() {
// this.loadObjTree();
},
computed: {},
watch: {
// 查询操作--监听父组件中经过查询操作后,得到的最新数据,重新加载ztree
searchedData(newInfo, oldInfo) {
this.initalNode = newInfo;
this.loadObjTree();
}
}
};
</script>
css部分
/* 修改图标样式---全局引入 */
.ztree li span.button.icon1_ico_open,
.ztree li span.button.icon1_ico_close {
background: url("https://s3.ax1x.com/2021/01/09/sMM9MQ.png") 0 0 no-repeat;
background-size: 23px 20px;
width: 30px;
height: 22px;
}
.ztree li span.button.icon2_ico_open,
.ztree li span.button.icon2_ico_close {
background: url("https://s3.ax1x.com/2021/01/09/sMM9MQ.png") 0 0 no-repeat;
background-size: 23px 20px;
width: 30px;
height: 22px;
}
使用Ztree
引入--组件Ztree
<Ztree
@changeAddFormVisible="changeAddFormVisible"
@changeViewVisible="changeViewVisible"
@handleReset="handleReset"
@changeModifyVisible="changemodifyDbFormVisible"
@delConfirm="delConfirm"
:searchedData="searchedData"
ref="ZtreeRef"
/>
api
- event
- changeAddFormVisible(treeNode)
- changeViewVisible(selectedNode, selectedNodeLevel) // 参数:点击选中的节点、选中节点的级别
- changeModifyVisible(treeNode, visible) // 参数:当前节点、控制修改框的显示与隐藏(点击修改时显示、修改成功后隐藏)
- delConfirm(): 点击删除时,弹出删除确认框
- handleReset(): 新增数据成功后调用重置表单方法
- 属性数据:
- earchedData(): 监听父组件中查找到的数据变化,重新加载树形图
- ref: 需要手动修改ztree组件中 请求地址、请求参数
- ZtreeRef delNode() addNode(newAddInfo) modifyNode(updatedinfo)
进行增、删、改操作时,需要向后台发送请求。我把发送请求的部分,放在了ztree组件中,因此需要手动修改ztree组件中 请求地址、请求参数
使用举例
删除
// 在ztree组件中调用 delConfirm ,显示确认删除对话框
delConfirm () {
this.$Modal.confirm({
title: '确认删除',
content: '<p>您确定删除该节点吗?</p>',
onOk: () => {
// 当点击删除确定之后,调用 ztree 中定义的删除节点的操作
this.$refs.ZtreeRef.delNode();
this.checkBoxVisible = false;
this.addDbFormVisible = false;
this.modifyDbFormVisible = false;
},
onCancel: () => {
this.$Message.info('取消删除!');
}
});
}
修改
changemodifyDbFormVisible(currentNode, isVisible) {
// 显示隐藏修改表单
this.modifyDbFormVisible = isVisible;
// 根据 currentNode 的值,回填表单项
},
modifyDbSubmit() {
// 当修改表单验证通过时
this.$refs.modifyDbFormRef.validate((valid) => {
if (valid) {
// 调用 ztree 组件中的 modifyNode ,并将修改的信息传递过去,ztree组件中发送请求提交修改内容,
this.$refs.ZtreeRef.modifyNode(modifyDbFormInfo);
} else {
this.$Message.error('Fail!');
}
});
},
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!