目录列表的增删改查

效果图:

一、渲染目录

1.1添加目录树标签

<div class="box">
          <a-directory-tree
              v-model:expandedKeys="expandedKeys"
              v-model:selectedKeys="selectedKeys"
              multiple
              :tree-data="treeData"
              style="background-color: #e5e5e5;"
          >
          </a-directory-tree>
      </div>

1.2调用接口查询并渲染目录

const expandedKeys = ref([]);
const selectedKeys = ref([]);
const treeData = ref([])
//获取目录信息
const getDirData = async () => {
    try {
        const res = await getAllDir({id: 2});//这儿的id是整个目录的id,根据这个id获取全部目录数据
        // 解析目录数据,确保每个目录对象有'title'和'key'属性
        const directories = res.data.data.directoryVOS.map(dir => ({
            title: dir.directoryName,
            key: String(dir.id), // 将id转换为字符串作为key
            children: dir.directoryVOS.map(subDir => ({ // 遍历一级目录的子目录(二级目录)
                title: subDir.directoryName,
                key: String(subDir.id),
                children: subDir.directoryVOS.map(subSubDir => ({ // 遍历二级目录的子目录(三级目录)
                    title: subSubDir.directoryName,
                    key: String(subSubDir.id),
                    isLeaf: true // 标记为叶子节点
                })),
            })),
        }));
        // 更新treeData
        treeData.value = directories;
        // 输出获取到的目录信息
        console.log(res, '------');
    } catch (error) {
        console.error('Error fetching directory data:', error);
    }
};
// 调用函数以获取目录信息,这里可以根据实际情况传递id值
getDirData();

注意:目录数据结构可根据打印的数据结构来修改,也可自行遍历添加四级五级获取目录数据逻辑

效果图就是上面的目录数据

二、添加一级目录

2.1增添新增按钮

<div class="box">
          <div style="margin-bottom: 10px;margin-top: 10px;text-align: center;">
              <a-button style="background-color: #e5e5e5;border: none;color: #000;" @click="addDir">数据资产表目录<PlusOutlined /></a-button>
          </div>
         
          <a-directory-tree
              v-model:expandedKeys="expandedKeys"
              v-model:selectedKeys="selectedKeys"
              multiple
              :tree-data="treeData"
              style="background-color: #e5e5e5;"
          >
          </a-directory-tree>
      </div>

2.2组件中加入新增一级目录模态框

  <!-- 新增一级目录 -->
  <a-modal v-model:open="isOpen" title="新增一级目录" style="text-align: center;">
    <a-form :v-model="DirData" :rules="rules">
      <a-form-item label="目录名称" name="directoryName" :rules="[{ required: true, message: '请输入目录名称' }]">
        <a-input v-model:value="DirData.directoryName"></a-input>
      </a-form-item>
    </a-form>
    <template #footer>
      <div class="modal-buttons">
        <a-button @click="cancelForm">取消</a-button>
        <a-button @click="createDir" type="primary">确认</a-button>
      </div>
    </template>
  </a-modal>

定义isOpen、DirData

const isOpen = ref(false);
const DirData = ref([])

2.3打开模态框并实现新增一级目录

//新增目录
const addDir = () =>{
  isOpen.value = true
}
//取消模态框
const cancelForm = () => {
  isOpen.value = false;
}
// 新增一级目录
const createDir = async () => {
  const directoryData = {
            directoryName: DirData.value.directoryName,
            superId:2,
        };
    const res = await createDirectory(directoryData);
        console.log('======', res);
        message.success('新增一级目录成功!')
        isOpen.value = false
        getDirData();
        // 更新treeData
        const newDirectory = res.data; // 假设返回的数据就是新创建的目录对象
        treeData.value.push(newDirectory); // 将新目录添加到treeData中    
};

三、添加菜单栏按钮和搜索框

3.1添加按钮

<div class="box">
          <div style="margin-bottom: 10px;margin-top: 10px;text-align: center;">
              <a-button style="background-color: #e5e5e5;border: none;color: #000;" @click="addDir">数据资产表目录<PlusOutlined /></a-button>
          </div>
          <a-input-search v-model:value="searchValue"  style="margin-bottom: 8px" placeholder="按数据资产表名称或目录名称查询" />
          <!-- 功能菜单 -->
          <div :style="menuStyle" v-if="NodeTreeItem">
            <a-space>
              <div>菜单</div>
              <div>
                <a-button  title="添加二级目录"  size="small" @click="addDirNext" ><PlusOutlined /></a-button>
                <a-button  title="编辑"  size="small" @click="editDir" ><EditOutlined /></a-button>
                <a-button  title="删除"  size="small" @click="showDeleteModal" ><DeleteOutlined :style="{ color: 'red'}"/></a-button>
                <a-button title="添加三级目录" size="small" @click="addDirThird"><PlusCircleOutlined /></a-button>
              </div>

                
            </a-space>
          </div>
          <a-directory-tree
              v-model:expandedKeys="expandedKeys"
              v-model:selectedKeys="selectedKeys"
              multiple
              :tree-data="treeData"
              style="background-color: #e5e5e5;"
              
          >
          </a-directory-tree>
      </div>

定义参数

// 右键单击节点时触发
const NodeTreeItem = ref([]);
const menuStyle = ref('');

3.2引入图标

import { CaretRightOutlined,PlusOutlined,PlusCircleOutlined, EditOutlined, DeleteOutlined} from '@ant-design/icons-vue'

如无法引入显示运行代码:

npm install --save @ant-design/icons-vue或
pnpm install --save @ant-design/icons-vue

四、添加各个按钮模态框

4.1添加二级、三级、编辑模态框组件

<!-- 新增二级目录 -->
  <a-modal v-model:open="isOpenNext" title="新增下级目录" style="text-align: center;">
    <a-form :v-model="DirDataNext" :rules="rules">
      <a-form-item label="目录名称" name="directoryName" :rules="[{ required: true, message: '请输入目录名称' }]">
        <a-input v-model:value="DirDataNext.directoryName"></a-input>
      </a-form-item>
    </a-form>
    <template #footer>
      <div class="modal-buttons">
        <a-button @click="cancelFormNext">取消</a-button>
        <a-button @click="createDirNext" type="primary">确认</a-button>
      </div>
    </template>
  </a-modal>
  <!-- 新增三级目录 -->
<a-modal v-model:open="isOpenThird" title="新增三级目录" style="text-align: center;">
  <a-form :v-model="DirDataThird" :rules="rules">
    <a-form-item label="目录名称" name="directoryName" :rules="[{ required: true, message: '请输入目录名称' }]">
      <a-input v-model:value="DirDataThird.directoryName"></a-input>
    </a-form-item>
  </a-form>
  <template #footer>
    <div class="modal-buttons">
      <a-button @click="cancelFormThird">取消</a-button>
      <a-button @click="createDirThird" type="primary">确认</a-button>
    </div>
  </template>
</a-modal>

  <!-- 编辑目录 -->
  <a-modal v-model:open="isOpenEdit" title="编辑目录" style="text-align: center;">
    <a-form :v-model="DirDataEdit" :rules="rules">
      <a-form-item label="目录名称" name="directoryName" :rules="[{ required: true, message: '请输入目录名称' }]">
        <a-input v-model:value="DirDataEdit.directoryName"></a-input>
      </a-form-item>
    </a-form>
    <template #footer>
      <div class="modal-buttons">
        <a-button @click="cancelFormEdit">取消</a-button>
        <a-button @click="EditDir" type="primary">保存</a-button>
      </div>
    </template>
  </a-modal>

 定义模态框各参数

const isOpenNext = ref(false);
const isOpenEdit = ref(false);
const isOpenThird = ref(false)

  const DirDataNext = ref([])
  const DirDataThird = ref([])
  const DirDataEdit = ref([])

4.2删除目录模态框 

<div class="box">
          <div style="margin-bottom: 10px;margin-top: 10px;text-align: center;">
              <a-button style="background-color: #e5e5e5;border: none;color: #000;" @click="addDir">数据资产表目录<PlusOutlined /></a-button>
          </div>
          <a-input-search v-model:value="searchValue" style="margin-bottom: 8px" placeholder="按数据资产表名称或目录名称查询" />
          <!-- 功能菜单 -->
          <div :style="menuStyle" v-if="NodeTreeItem">
            <a-space>
              <div>菜单</div>
              <div>
                <a-button  title="添加二级目录"  size="small" @click="addDirNext" ><PlusOutlined /></a-button>
                <a-button  title="编辑"  size="small" @click="editDir" ><EditOutlined /></a-button>
                <a-button  title="删除"  size="small" @click="showDeleteModal" ><DeleteOutlined :style="{ color: 'red'}"/></a-button>
                <a-button title="添加三级目录" size="small" @click="addDirThird"><PlusCircleOutlined /></a-button>
              </div>

                <a-modal v-model:visible="deleteModalVisible" style="text-align: center;">
                  <p style="font-size: 20px;margin-top: 20px;"><ExclamationCircleOutlined :style="{ color: 'red'}"/>  确定要删除该目录吗?</p>
                  
                  <template #footer>
                    <div style="display: flex; justify-content: center; margin-top: 20px;">
                      <a-button @click="handleDelete" type="primary" style="margin-right: 10px;">确认</a-button>
                      <a-button @click="cancelDelete">取消</a-button>
                    </div>
                  </template>
                </a-modal>
            </a-space>
          </div>
          <a-directory-tree
              v-model:expandedKeys="expandedKeys"
              v-model:selectedKeys="selectedKeys"
              multiple
              :tree-data="treeData"
              style="background-color: #e5e5e5;"
          >
          </a-directory-tree>
      </div>

定义参数

const deleteModalVisible = ref(false);

 引入图标

import { CaretRightOutlined,PlusOutlined,PlusCircleOutlined, EditOutlined, DeleteOutlined,ExclamationCircleOutlined} from '@ant-design/icons-vue'

 4.3点击按钮打开模态框

//新增二级目录
const addDirNext = () =>{
  isOpenNext.value = true
  DirDataNext.value = {}
}
//取消模态框
const cancelFormNext = () => {
  isOpenNext.value = false;
}


// 新增三级目录
const addDirThird = () => {
  isOpenThird.value = true;
  DirDataThird.value = {};
};

//取消模态框(三级目录)
const cancelFormThird = () => {
  isOpenThird.value = false;
};

// 编辑目录
const editDir = () => {
  // 填充编辑表单数据
  DirDataEdit.value.directoryName = NodeTreeItem.value.title; // 使用右键点击的节点的名称填充编辑表单
  // 打开二级目录模态框
  isOpenEdit.value = true;
};
//取消模态框
const cancelFormEdit = () => {
  isOpenEdit.value = false;
}

//删除目录
const showDeleteModal = () => {
  deleteModalVisible.value = true;
};

const cancelDelete = () => {
  // 取消删除操作,关闭模态框
  deleteModalVisible.value = false;
};

 

 

 

 

五、目录树添加右键点击事件

5.1目录树添加@rightClick="onRightClick"

<a-directory-tree
              v-model:expandedKeys="expandedKeys"
              v-model:selectedKeys="selectedKeys"
              multiple
              :tree-data="treeData"
              style="background-color: #e5e5e5;"
              @rightClick="onRightClick"
          >
          </a-directory-tree>

5.2实现点击逻辑

const onRightClick = ({ event, node }) => {
    const x = event.currentTarget.offsetLeft + event.currentTarget.clientWidth;
    const y = event.currentTarget.offsetTop;

    NodeTreeItem.value = {
        pageX: x,
        pageY: y,
        id: node.key, // 使用节点的 key 属性作为唯一标识符
        title: node.title, // 使用节点的 title 属性作为显示名称
        parentOrgId: node.superId || null // 如果有的话,使用节点的父级 ID 属性作为父级组织的标识符
    };
    // 设置菜单位置和样式
    menuStyle.value = `
        maxHeight: 40;
        textAlign: center;
        left: ${x + 4 - 0}px;
        top: ${y + 4 - 0}px;
        display: flex;
        flexDirection: row;
    `;
};

注意:该点击事件是右击选中当前目录进行各个功能操作(增加、删除、修改)

六、添加各个功能逻辑

6.1增加、删除、修改

//新增二级目录
const createDirNext = async (directoryName:String, superId:Number) => {
  const directoryData = {
            // directoryDescription: directoryDescription,..,
            directoryName: DirDataNext.value.directoryName,
            superId: NodeTreeItem.value.id,
        };
    const res = await createDirectory(directoryData);
        console.log('======', res);
        
        if (res.data.code === 200) {
          // 这里可以执行成功后的逻辑,比如提示成功或其他操作
          message.success('新增二级目录成功!')
          isOpenNext.value = false
          getDirData();
        } else if (res.data.code === 500) {
          // 如果测试失败,提示失败信息
          message.error(res.data.msg); // 显示后端返回的错误信息
        }
        // 更新treeData
        const newDirectory = res.data; // 假设返回的数据就是新创建的目录对象
        treeData.value.push(newDirectory); // 将新目录添加到treeData中    
};

//新增三级目录
const createDirThird = async (directoryName:String, superId:Number) => {
  const directoryData = {
    directoryName: DirDataThird.value.directoryName,
    superId: NodeTreeItem.value.id,
  };
  const res = await createDirectory(directoryData);
  console.log('=====ssss=', res);
  if (res.data.code === 200) {
    // 这里可以执行成功后的逻辑,比如提示成功或其他操作
    message.success('新增三级目录成功!')
    isOpenThird.value = false;
    getDirData();
    } else if (res.data.code === 500) {
          // 如果测试失败,提示失败信息
      message.error(res.data.msg); // 显示后端返回的错误信息
    }      
  // 更新treeData
  const newDirectory = res.data; // 假设返回的数据就是新创建的目录对象
  treeData.value.push(newDirectory); // 将新目录添加到treeData中
};

const EditDir = async () => {
  const directoryData = {
            directoryName: DirDataEdit.value.directoryName,
            id: parseInt(NodeTreeItem.value.id), // 将字符串ID转换为数字
        };
    const res = await updateDirectory(directoryData,directoryData.id);
        // console.log(NodeTreeItem.value,'=-=-=-=-=');
        message.success('目录修改成功!')
        isOpenEdit.value = false
        getDirData();
        // 更新treeData
        const newDirectory = res.data; // 假设返回的数据就是新创建的目录对象
        treeData.value.push(newDirectory); // 将新目录添加到treeData中    
};

const handleDelete = async() => {
  await deleteDirectory(NodeTreeItem.value.id);
  deleteModalVisible.value = false
  message.success('目录删除成功!')
  getDirData()
};

注意:在新增三级目录注意是第四个按钮

6.2查询

6.2.1添加change事件

<a-input-search v-model:value="searchValue" @change="searchDir"  style="margin-bottom: 8px" placeholder="按数据资产表名称或目录名称查询" />

定义

const searchValue = ref('');

6.2.2查询逻辑

// 在函数外部声明 enumOptions
const enumOptions = ref([]);
// 处理搜索事件
const searchDir = async () => {
  try {
    // 调用接口搜索目录数据
    const response = await selectDirectoryByName({ name: searchValue.value.trim() });
    // 假设您的搜索接口返回的是一个数组,表示搜索结果
    const directories = response.data.data;
    if (directories && directories.length > 0) {
      // 将搜索结果转换为树形结构
      const treeData = transformToTreeData(directories);
      // 设置展开和选中的节点
      expandedKeys.value = getExpandedKeys(treeData);
      selectedKeys.value = getSelectedKeys(treeData);
      // 更新树形目录数据
      enumOptions.value = treeData;
    } else {
      // 如果未搜索到目录,则清空展开和选中的节点
      clearSelection();
    }
  } catch (error) {
    console.error('搜索目录失败:', error);
  }
};

// 将搜索结果转换为树形结构
const transformToTreeData = (directories) => {
  // 假设您的目录对象中有一个 children 字段,用于存储子目录
  return directories.map(dir => ({
    title: dir.name,
    key: String(dir.id),
    children: dir.children ? transformToTreeData(dir.children) : [],
  }));
};

// 获取需要展开的节点的 keys
const getExpandedKeys = (treeData) => {
  const keys = [];
  treeData.forEach(node => {
    // 如果节点是搜索结果的直接父节点,则需要展开
    if (node.children.length > 0) {
      keys.push(node.key);
    }
  });
  return keys;
};

// 获取需要选中的节点的 keys
const getSelectedKeys = (treeData) => {
  const keys = [];
  treeData.forEach(node => {
    // 如果节点是搜索结果的叶子节点,则需要选中
    if (node.children.length === 0) {
      keys.push(node.key);
    }
  });
  return keys;
};

注意:现在我只有查询到一级目录并定位,二级三级可自行修改实现

!!!各个接口信息自行引入并添加

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值