zTree api documentation: https://www.treejs.cn/v3/api.php
1. Initialization tree configuration items
const initZtreeSetting = () => {<!-- --> const setting = {<!-- --> view: {<!-- --> addHoverDom: addHoverDom, // Display user-defined controls selectedMulti: false,//Whether multiple nodes are allowed to be selected at the same time, the default is true showIcon: true, //Whether to display the icon of the node, the default is true }, data: {<!-- --> simpleData: {<!-- -->//Use simple data mode enable: true, idKey: 'id', pIdKey: 'parentId', rootPId: 0, }, }, callback: {<!-- --> onClick: handleNodeClick, // callback function when the node is clicked beforeClick: handleNodeBeforeClick, //Callback function before the node is clicked, set whether the node can be clicked }, }; return setting; };
2. Customized action buttons
const addHoverDom = (treeId, treeNode) => {<!-- --> let addStr = null; const add = `<span class='button add' id='btn_add_${<!-- -->treeNode.tId}' title='Add file' οnfοcus='this.blur();'></span >`; const addSm = `<span class='button addSm' id='btn_addSm_${<!-- -->treeNode.tId}' title='Add Node' οnfοcus='this.blur();'></span >`; const edit = `<span class='button edit' id='btn_edit_${<!-- -->treeNode.tId}' title='Edit' οnfοcus='this.blur();'></span> `; const del = `<span class='button remove' id='btn_remove_${<!-- -->treeNode.tId}' title='Delete' οnfοcus='this.blur();'></span> `; if (treeNode.id === 'custom') {<!-- --> // customize addStr = addSm; //Add node } else if (treeNode.code === 'custom') {<!-- --> // Customized classification nodes (second level) if (treeNode.pid === 'custom') {<!-- --> addStr = add + edit; if (_.isEmpty(treeNode.children)) {<!-- --> addStr + = del; // When a child node is placed under a category, the category can be deleted } } else {<!-- --> //Three layers addStr = edit + del; } if (addStr) {<!-- --> const _id = `#${<!-- -->treeNode.tId}_span`; tippy(_id, {<!-- --> content: addStr, // Prompt content trigger: 'mouseenter click',// trigger method placement: 'right', // Appearance position interactive: true,//Whether it is possible to interact theme: 'material',// theme onMount: function () {<!-- -->// Execute after mounting $(`#btn_edit_${<!-- -->treeNode.tId}`) ?.off('click') ?.on('click', (e) => {<!-- --> editNode(treeId, treeNode); e.stopPropagation(); }); $(`#btn_add_${<!-- -->treeNode.tId}`) ?.off('click') ?.on('click', (e) => {<!-- --> addNode(treeId, treeNode); e.stopPropagation(); }); $(`#btn_addSm_${<!-- -->treeNode.tId}`) ?.off('click') ?.on('click', (e) => {<!-- --> saveSmNode('add', treeId, treeNode); e.stopPropagation(); }); $(`#btn_remove_${<!-- -->treeNode.tId}`) ?.off('click') ?.on('click', (e) => {<!-- --> removeNode(treeId, treeNode); e.stopPropagation(); }); }, }); } };
tippy api documentation: https://atomiks.github.io/tippyjs/v6/all-props
3. Button binding event
//Add and edit nodes (category) async function saveSmNode(type: 'add' | 'mod', treeId, treeNode) {<!-- --> const title = type === 'add' ? 'New node' : 'Edit node'; let {<!-- --> value } = await ElMessageBox.prompt(title, '', {<!-- --> confirmButtonText: 'Confirm', cancelButtonText:'Cancel', inputPattern: /\S + /,// Input box verification rules inputPlaceholder: type === 'add' ? 'Please enter the node name' : null, // placeholder inputErrorMessage: 'Node name cannot be empty! ',//Verification failed information inputValue: type === 'add' ? null : treeNode.name,//default value of input box }); try {<!-- --> //case1: Add a new node under this node if (type === 'add') {<!-- --> const res = await $.ajax({<!-- --> url: `${<!-- -->window.__ctx}/report/module/addNode`, type: 'POST', dataType: 'json', data: {<!-- --> parentId: treeNode.id, name: value,//Get the value of the input box }, }); if (!res.result) throw new Error(res?.message); ElMessage.success(res?.message || 'Submission successful'); const zTreeObj = $.fn.zTree.getZTreeObj(treeId); zTreeObj.addNodes(treeNode, res?.object);//Update the display of tree nodes //case2: Edit the node } else {<!-- --> const res = await $.ajax({<!-- --> url: `${<!-- -->window.__ctx}/report/module/rename`, type: 'POST', dataType: 'json', data: {<!-- --> id: treeNode.id, reName: value, }, }); if (!res.result) throw new Error(res?.message); ElMessage.success(res?.message || 'Submission successful'); const zTreeObj = $.fn.zTree.getZTreeObj(treeId); treeNode.name = value; zTreeObj.updateNode(treeNode); } } catch (error) {<!-- --> if (error === 'cancel') return; ElMessage.error(error?.message ||'Submission failed'); console.log(`addSmNode - error`, error); } } // delete async function removeNode(treeId, treeNode) {<!-- --> try {<!-- --> const modId = treeNode.id; await ElMessageBox.confirm('Do you want to delete this node?', 'Prompt', {<!-- --> confirmButtonText: 'Confirm', cancelButtonText:'Cancel', type: 'warning', }); const res = await $.ajax({<!-- --> url: `${<!-- -->window.__ctx}/report/module/delete/${<!-- -->modId}`, type: 'GET', dataType: 'json', }); if (!res.result) throw new Error(res?.message); ElMessage.success(res?.message || 'Submission successful'); $.fn.zTree.getZTreeObj(treeId).removeNode(treeNode);//Remove the node } catch (error) {<!-- --> if (error === 'cancel') return; ElMessage.error(error?.message || 'Submission failed'); console.log(`removeNode - error`, error); } } // add files function addNode(treeId, treeNode) {<!-- --> ... } //Edit file function editNode(treeId, treeNode) {<!-- --> ... }
4. Interface request data, initialize zTree
async function initZtree() {<!-- --> const setting = initZtreeSetting (); try {<!-- --> isTreeLoading.value = true; const res = await $.ajax({<!-- --> url: `${<!-- -->window.__ctx}/report/tree`, type: 'POST', dataType: 'json', }); if (!res?.result) return; const treeObj = $.fn.zTree.init($('#treeId'), setting, res?.object); if (treeObj.getNodes().length >= 1) {<!-- --> treeObj.expandNode(treeObj.getNodes()[0], true);//Expand the first node } } catch (err) {<!-- --> console.log(`[log] - initZtree- err`, err); } finally {<!-- --> isTreeLoading.value = false; } }
5. All code
<template> <div v-loading="isTreeLoading"> <ul class="ztree" id="treeId"></ul> </div> </template>