antdvue的tree组件增加增删改功能

这篇博客展示了如何在Vue.js应用中使用Ant Design Vue库创建一个具有树形结构的数据操作组件。内容包括:1) 添加节点;2) 编辑节点,包括输入框验证和保存;3) 删除节点;4) 显示不同状态的图标。通过自定义插槽和事件监听,实现了树节点的动态编辑和管理。
摘要由CSDN通过智能技术生成

在这里插入图片描述

<template>
  <div>
    <a-tree :treeData="treeData">
      <span slot="switcherIcon" class="icon-plus"></span>
      <template slot="custom" slot-scope="item">
        <!-- if -->
        <span v-if="item.isNewItem">
          <a-input placeholder="请输入内容" class="editInput" v-model="item.name" />
          <span class="tree-cancle_icon edit-require_icon">
            <a-icon type="close-circle" style="font-size:16px" @click="closecontent(item)" />
          </span>
          <span class="tree-save_icon edit-require_icon">
            <a-icon type="check-circle" style="font-size:16px" @click="addinputcontent(item)" />
          </span>
        </span>
        <!-- else -->
        <div v-else>
          <!-- 如果是修改 -->
          <div v-if="item.isEdit">
            <a-input v-model="item.title" class="editInput" />
            <span class="tree-cancle_icon edit-require_icon" @click="editnocontent(item)">
              <a-icon type="close-circle" />
            </span>
            <span class="tree-save_icon edit-require_icon" @click="edityescontent(item)">
              <a-icon type="check-circle" />
            </span>
          </div>
          <div v-else>
            <span class="node-title">{{ item.title }}</span>
            <span class="icon-wrap" @click="addNode(item)">
              <a-icon type="plus" />
            </span>
            <span class="icon-wrap" @click="editNode(item)">
              <a-icon type="form" />
            </span>
            <a-popconfirm title="确定删除吗?" ok-text="确定" cancel-text="取消" @confirm="confirm" @cancel="cancel">
              <span class="icon-wrap" @click="delNode(item)">
                <a-icon type="delete" />
              </span>
            </a-popconfirm>
          </div>
        </div>
      </template>
    </a-tree>
  </div>
</template>
<script>
export default {
  data() {
    return {
      codeArray: [],
      treeData: [
        {
          id: 9,
          key: 0,
          isEdit: false,
          isNewItem: false,
          title: '七年级',
          depth: 1,
          scopedSlots: { title: 'custom' },
          children: []
        },
        {
          id: 10,
          key: 1,
          isEdit: false, // 是否处于编辑状态
          isNewItem: false, // 该节点是否是新增节点
          title: '八年级',
          depth: 1, // 该节点的层级
          scopedSlots: { title: 'custom' }, // 自定义组件需要绑定
          children: [
            {
              id: 2,
              key: 2,
              isEdit: false, // 是否处于编辑状态
              isNewItem: false, // 该节点是否是新增节点
              title: '八(一)班',
              depth: 2, // 该节点的层级
              scopedSlots: { title: 'custom' }
            }
          ]
        },
        {
          id: 11,
          key: 2,
          isEdit: false,
          isNewItem: false,
          title: '九年级',
          depth: 1,
          scopedSlots: { title: 'custom' },
          children: []
        }
      ]
    };
  },
  watch: {},
  methods: {
    confirm(e) {
      console.log(e);
      this.$message.success('Click on Yes');
    },
    cancel(e) {
      this.$message.error('取消操作');
    },
    addNode(item) {
      //点击新增
      console.log(this.treeData,'aaaa', item);
      let code = item.pos.replace(/-/g, '');
      let codeArray = code.split('');
      this.codeArray = codeArray;
      let newNode = {
        id: Math.ceil(Math.random() * 10000), //避免和已有的id冲突
        key: Math.ceil(Math.random() * 10000), //避免和已有的key冲突
        isEdit: false,
        name: '',
        isNewItem: true,
        title: '',
        depth: item.depth + 1, //如需要添加顶级节点,值为0
        scopedSlots: { title: 'custom' },
        children: []
      };
      let index = item.depth - 1;
      console.log(codeArray)
      this.treeData[codeArray[1]].children.push(newNode);
    },
    editnocontent(item){  //修改的时候的叉叉
      let codeArray = this.codeArray;
      let treeData = this.treeData
      function queryindex(x){  //[1,2]
        if(x.length == 1){
          return treeData[codeArray[0]].isEdit = false;
        }else{
          return treeData[codeArray[0]].children[codeArray[1]].isEdit = false
        }
      }
      queryindex(codeArray)
    },
    edityescontent(item){ //修改时候的对号
      let codeArray = this.codeArray;
      let treeData = this.treeData
      function queryindex(x){  //[1,2]
        if(x.length == 1){
          treeData[codeArray[0]].isEdit = false
          return treeData[codeArray[0]].title = item.title;
        }else{
          treeData[codeArray[0]].children[codeArray[1]].isEdit = false
          return treeData[codeArray[0]].children[codeArray[1]].title = item.title
        }
      }
      queryindex(codeArray)
    },
    addinputcontent(item) {
      //点击确定
      let newNode = {
        id: item.id, //避免和已有的id冲突
        key: item.key, //避免和已有的key冲突
        isEdit: false,
        isNewItem: false,
        title: item.name,
        depth: item.depth + 1, //如需要添加顶级节点,值为0
        scopedSlots: { title: 'custom' },
        children: []
      };
      let codeindex = this.codeArray[1];
      this.treeData[codeindex].children.pop();
      this.treeData[codeindex].children.push(newNode);
    },
    closecontent(item) {
      //点击叉掉
      console.log(item);
      let code = item.pos.replace(/-/g, '');
      let codeArray = code.split('');
      codeArray.shift();
      this.treeData[codeArray[0]].children.splice(codeArray[1],1);
    },
    editNode(item) {
      //点击修改
      let code = item.pos.replace(/-/g, '');
      let codeArray = code.split('');
      codeArray.shift();
      this.codeArray = codeArray;
      let treeData = this.treeData
      function queryindex(x){  //[1,2]
        if(x.length == 1){
          return treeData[codeArray[0]].isEdit = true;
        }else{
          return treeData[codeArray[0]].children[codeArray[1]].isEdit = true
        }
      }
      queryindex(codeArray)
    },
    delNode(item) {
      //删除
      let code = item.pos.replace(/-/g, '');
      let codeArray = code.split('');
      codeArray.shift();
      let treeData = this.treeData
      function queryindex(x){  //[1,2]
        if(x.length == 1){
          treeData.splice(codeArray[0],1);
        }else{
          treeData[codeArray[0]].children.splice(codeArray[1],1);
        }
      }
      queryindex(codeArray)
    }
  }
};
</script>
<style lang="scss" scoped>
::v-deep .ant-tree-switcher.ant-tree-switcher_open {
  .icon-plus {
    background-image: url("./minus.png") ; // 展开节点时的icon
    background-size: 24px;
    width: 24px;
    height: 24px;
  }
}
::v-deep .ant-tree-switcher.ant-tree-switcher_close {
  .icon-plus {
    background-image: url("./add.png") ; // 收起节点时的icon
    background-size: 24px;
    width: 24px;
    height: 24px;
  }
}
.icon-wrap {
  margin: 0 6px;
}
.node-title {
  padding-right: 15px;
}
.tree-cancle_icon {
  margin: 0 6px;
}
</style>
Ant Design (antd) 是一套基于 React 的 UI 组件库,其中的 Tree 是用于展示层级数据的组件。在处理树形结构的增删操作时,你可以按照以下步骤进行: 1. **创建 Tree 组件**: 首先,在你的 Ant Design 应用中引入 `Tree` 和相关的 API,例如 `TreeNode`。 ```jsx import { Tree, TreeNode } from 'antd'; ``` 2. **数据模型**: 定义你的节点数据模型,包含节点的 key、label(标签)、children(子节点数组)等属性。 ```jsx const data = [ { title: '父节点', key: '0-0', children: [ { title: '子节点1', key: '0-0-1' }, { title: '子节点2', key: '0-0-2' } ] } ]; ``` 3. **添加节点**: 可以通过修数据模型来添加新节点,然后触发树组件的 `onAdd` 或者 `onChange` 事件来同步更新视图。 ```jsx let newNode = { title: '新增节点', key: uuidv4(), // 使用随机 UUID 作为节点唯一标识 }; data.push(newNode); // 添加到当前层级 if (treeProps.onChange) { treeProps.onChange(newNode, 'add'); } ``` 4. **删除节点**: 删除节点时,同样需要从数据源中移除,并通过 `onDelete` 或者 `onChange` 事件通知组件。 ```jsx function deleteNode(nodeKey) { const index = data.findIndex(n => n.key === nodeKey); if (index !== -1) { data.splice(index, 1); if (treeProps.onChange) { treeProps.onChange(null, 'delete', nodeKey); } } } ``` 5. **编辑节点**: 如果需要支持编辑节点内容,通常会在点击节点时弹出输入框让用户修,然后修数据模型并触发相应的事件。 6. **注意事项**: - 在实际应用中,你需要将这些操作封装成函数,并可能需要考虑状态管理(如 Redux、MobX 等)来统一处理数据变化。 - 调整 Tree 的展开/收起状态可能需要用到 `onSelect` 和 `onExpand` 事件。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值