【zTree】节点添加不同操作按钮,点击后生成弹窗

zTree api 文档:https://www.treejs.cn/v3/api.php

1. 初始化树的配置项

const initZtreeSetting = () => {
  const setting = {
    view: {
      addHoverDom: addHoverDom, // 显示用户自定义控件
      selectedMulti: false,// 是否允许同时选中多个节点,默认为true
      showIcon: true,//是否显示节点的图标,默认为true
    },
    data: {
      simpleData: {// 使用用简单数据模式
        enable: true,
        idKey: 'id',
        pIdKey: 'parentId',
        rootPId: 0,
      },
    },
    callback: {
      onClick: handleNodeClick,// 节点被点击的回调函数
      beforeClick: handleNodeBeforeClick,//节点被点击前的回调函数,设置节点是否可以点击
    },
  };
  return setting;
};

2. 自定义操作按钮

【zTree】节点添加不同操作按钮,点击后生成弹窗_第1张图片

const addHoverDom = (treeId, treeNode) => {
  let addStr = null;
  const add = ``;
  const addSm = ``;
  const edit = ``;
  const del = ``;
  
  if (treeNode.id === '自定义') {
    // 自定义
    addStr = addSm; // 添加节点
  } else if (treeNode.code === 'custom') {
    // 自定义下的分类节点(二层)
    if (treeNode.pid === '自定义') {
      addStr = add + edit;
      if (_.isEmpty(treeNode.children)) {
        addStr += del; // 分类下子节点时,可删除该分类
      }
    } else {
      // 三层
      addStr = edit + del;
    }
    
  if (addStr) {
    const _id = `#${treeNode.tId}_span`;
    tippy(_id, {
      content: addStr,// 提示的内容
      trigger: 'mouseenter click',// 触发方式
      placement: 'right',// 出现位置
      interactive: true,// 是否可以交互
      theme: 'material',// 主题
      onMount: function () {// 挂载后执行
        $(`#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文档:https://atomiks.github.io/tippyjs/v6/all-props

3. 按钮绑定事件

// 添加、编辑节点(分类)
async function saveSmNode(type: 'add' | 'mod', treeId, treeNode) {
  const title = type === 'add' ? '新增节点' : '编辑节点';
  let { value } = await ElMessageBox.prompt(title, '', {
    confirmButtonText: '确认',
    cancelButtonText:'取消',
    inputPattern: /\S+/,// 输入框校验规则
    inputPlaceholder: type === 'add' ? '请输入节点名称' : null,// 占位符
    inputErrorMessage: '节点名不能为空!',// 校验不通过的信息
    inputValue: type === 'add' ? null : treeNode.name,// 输入框默认值
  });
  try {
   //case1: 在该节点下新增节点
    if (type === 'add') {
      const res = await $.ajax({
        url: `${window.__ctx}/report/module/addNode`,
        type: 'POST',
        dataType: 'json',
        data: {
          parentId:treeNode.id,
          name: value,// 获取到输入框的值
        },
      });
      if (!res.result) throw new Error(res?.message);
      ElMessage.success(res?.message || '提交成功');
      const zTreeObj = $.fn.zTree.getZTreeObj(treeId);
      zTreeObj.addNodes(treeNode , res?.object);// 更新树节点的显示
     //case2:对该节点进行编辑
    } 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 || '提交成功');
      const zTreeObj = $.fn.zTree.getZTreeObj(treeId);
      treeNode.name = value;
      zTreeObj.updateNode(treeNode);
    }
  } catch (error) {
    if (error === 'cancel') return;
    ElMessage.error(error?.message ||'提交失败');
    console.log(`addSmNode - error`, error);
  }
}

// 删除
async function removeNode(treeId, treeNode) {
  try {
    const modId = treeNode.id;
    await ElMessageBox.confirm('是否要删除该节点?', '提示', {
   	  confirmButtonText: '确认',
 	  cancelButtonText:'取消',
      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 || '提交成功');
    $.fn.zTree.getZTreeObj(treeId).removeNode(treeNode);//移除该节点
  } catch (error) {
    if (error === 'cancel') return;
    ElMessage.error(error?.message || '提交失败');
    console.log(`removeNode - error`, error);
  }
}
// 添加文件
function addNode(treeId, treeNode) {
  ...
}
// 编辑文件
function editNode(treeId, treeNode) {
  ...
}

4. 接口请求数据, 初始化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);// 展开第一个节点
    }
  } catch (err) {
    console.log(`[log] - initZtree- err`, err);
  } finally {
    isTreeLoading.value = false;
  }
}

5. 全部代码

<template>
    <div v-loading="isTreeLoading">
      <ul class="ztree" id="treeId">ul>
    div>
template>
<script setup lang="ts">
import { ref } from 'vue';
const isTreeLoading = ref(false);

// 初始化树的配置项
const initZtreeSetting = () => {
  const setting = {
    view: {
      addHoverDom: addHoverDom, // 显示用户自定义控件
      selectedMulti: false,// 是否允许同时选中多个节点,默认为true
      showIcon: true,//是否显示节点的图标,默认为true
    },
    data: {
      simpleData: {// 使用用简单数据模式
        enable: true,
        idKey: 'id',
        pIdKey: 'parentId',
        rootPId: 0,
      },
    },
    callback: {
      onClick: handleNodeClick,// 节点被点击的回调函数
      beforeClick: handleNodeBeforeClick,//节点被点击前的回调函数,设置节点是否可以点击
    },
  };
  return setting;
};
// 节点前点击事件
const handleNodeBeforeClick = (treeId, treeNode, clickFlag) => {
  return treeNode.reportType !== 'Node';// 返回 false,无法点击
};
// 节点点击事件
const handleNodeClick = (event, treeId, treeNode) => {
  console.log(`treeNode->`, treeNode);
};
// 初始化树
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);// 展开第一个节点
    }
  } catch (err) {
    console.log(`[log] - initZtree- err`, err);
  } finally {
    isTreeLoading.value = false;
  }
}
onMounted(() => {
  initZtree();
});

//自定义操作按钮
const addHoverDom = (treeId, treeNode) => {
  let addStr = null;
  const add = ``;
  const addSm = ``;
  const edit = ``;
  const del = ``;
  
  if (treeNode.id === '自定义') {
    // 自定义
    addStr = addSm; // 添加节点
  } else if (treeNode.code === 'custom') {
    // 自定义下的分类节点(二层)
    if (treeNode.pid === '自定义') {
      addStr = add + edit;
      if (_.isEmpty(treeNode.children)) {
        addStr += del; // 分类下子节点时,可删除该分类
      }
    } else {
      // 三层
      addStr = edit + del;
    }
    
  if (addStr) {
    const _id = `#${treeNode.tId}_span`;
    tippy(_id, {
      content: addStr,// 提示的内容
      trigger: 'mouseenter click',// 触发方式
      placement: 'right',// 出现位置
      interactive: true,// 是否可以交互
      theme: 'material',// 主题
      onMount: function () {// 挂载后执行
        $(`#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();
          });
      },
    });
  }
};

// 添加、编辑节点(分类)
async function saveSmNode(type: 'add' | 'mod', treeId, treeNode) {
  const title = type === 'add' ? '新增节点' : '编辑节点';
  let { value } = await ElMessageBox.prompt(title, '', {
    confirmButtonText: '确认',
    cancelButtonText:'取消',
    inputPattern: /\S+/,// 输入框校验规则
    inputPlaceholder: type === 'add' ? '请输入节点名称' : null,// 占位符
    inputErrorMessage: '节点名不能为空!',// 校验不通过的信息
    inputValue: type === 'add' ? null : treeNode.name,// 输入框默认值
  });
  try {
   //case1: 在该节点下新增节点
    if (type === 'add') {
      const res = await $.ajax({
        url: `${window.__ctx}/report/module/addNode`,
        type: 'POST',
        dataType: 'json',
        data: {
          parentId:treeNode.id,
          name: value,// 获取到输入框的值
        },
      });
      if (!res.result) throw new Error(res?.message);
      ElMessage.success(res?.message || '提交成功');
      const zTreeObj = $.fn.zTree.getZTreeObj(treeId);
      zTreeObj.addNodes(treeNode , res?.object);// 更新树节点的显示
     //case2:对该节点进行编辑
    } 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 || '提交成功');
      const zTreeObj = $.fn.zTree.getZTreeObj(treeId);
      treeNode.name = value;
      zTreeObj.updateNode(treeNode);
    }
  } catch (error) {
    if (error === 'cancel') return;
    ElMessage.error(error?.message ||'提交失败');
    console.log(`addSmNode - error`, error);
  }
}

// 删除
async function removeNode(treeId, treeNode) {
  try {
    const modId = treeNode.id;
    await ElMessageBox.confirm('是否要删除该节点?', '提示', {
   	  confirmButtonText: '确认',
 	  cancelButtonText:'取消',
      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 || '提交成功');
    $.fn.zTree.getZTreeObj(treeId).removeNode(treeNode);//移除该节点
  } catch (error) {
    if (error === 'cancel') return;
    ElMessage.error(error?.message || '提交失败');
    console.log(`removeNode - error`, error);
  }
}
// 添加文件
function addNode(treeId, treeNode) {
  ...
}
// 编辑文件
function editNode(treeId, treeNode) {
  ...
}

</script >

你可能感兴趣的:(zTree,vue.js,jquery,前端,vue)