vue-antd tree组件自定义增删改功能

在VMS2.0 开发过程中,使用了vue-antd组件。然而,根据产品和交互的需求,需要实现以下设计稿的效果。使得用户可以直接在树节点上直接操作。

通过调研发现,vue-antd 自带的组件库只能实现以下样式展现,并不能直接在树节点上进行操作。

网上资料也搜寻了很多,无果,所以只能自己动手。最终实现效果如下图:
(顶级节点不能删除 为业务需求,可以忽略)


可以看到,新增、编辑和删除的具体实现效果。实现步骤如下:
一,数据格式

	<a-tree :treeData="testData"></a-tree>
	let treeData = [
        {
          id: 1,
          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" }
            }
          ]
        }
      ];

目前效果:

设置树节点的icon

<a-tree :treeData="testData">
	<span slot="switcherIcon" class="icon-plus"></span>
</tree>

<style lang="less" scoped> 
/deep/ .ant-tree-switcher.ant-tree-switcher_open {
  .icon-plus {
    background-image: url("~@/assets/minus.png"); // 展开节点时的icon
  }
}
/deep/ .ant-tree-switcher.ant-tree-switcher_close {
  .icon-plus {
    background-image: url("~@/assets/plus.png"); // 收起节点时的icon
  }
}

</style>


二,增删改 按钮展示

<a-tree :treeData="testData">
        <span slot="switcherIcon" class="icon-plus"></span>
        <template slot="custom" slot-scope="item">
          <span class="node-title">{{ item.title }} </span>
          <span class="icon-wrap">
            <icon name="delete" />
          </span>
          <span class="icon-wrap">
            <icon name="edit" />
          </span>
          <span class="icon-wrap">
            <icon name="plus" />
          </span>
        </template>
      </a-tree>

效果果如下图(样式部分省略):

二,新增功能
template会渲染每个节点,我们新增元素时,应该展示一个输入框,待用户输入新节点名称。于是可以创建一个空间点,通过 isNewItem:true来展示输入框。

	<template slot="custom" slot-scope="item">
          <!-- 如果是新节点 -->
          <span v-if="item.isNewItem">
            <input type="text" class="editInput" v-model="item.name" />
            <span class="tree-cancle_icon edit-require_icon">
              <a-icon type="close-circle" />
            </span>
            <span class="tree-save_icon edit-require_icon">
              <a-icon type="check-circle" />
            </span>
          </span>
          <span v-else>
            <span class="node-title">{{ item.title }} </span>
            <span class="icon-wrap">
              <icon name="delete" />
            </span>
            <span class="icon-wrap" @click="editNode(item)">
              <icon name="edit" />
            </span>
            <span class="icon-wrap" @click="addNewNode(item)">
              <icon name="plus" />
            </span>
          </span>
        </template>


	<script>
		点击添加事件( item ){  // item为点击添加按钮时的节点
		 let newItem = {
		  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: []
		}
		// index 是点击节点的位置
		this.treeData[index].children.push(newNode);
	</script>

效果如下(样式省略)

二,编辑功能
编辑的话,只需要在原节点上进行操作。所以我们在 v-else进行操作。

	<div v-else>
		<!-- 编辑时展示输入框 -->
      <div v-if="item.isEdit">
        <input type="text" v-model="item.title" class="editInput" />
        <span class="tree-cancle_icon edit-require_icon">
			<a-icon type="close-circle" />
		  </span>
        <span class="tree-save_icon edit-require_icon" >
			<a-icon type="check-circle" />
	     </span>
      </div>
		<!-- 否则展示原来的节点信息 -->
	    <div v-else>
			 <span class="node-title">{{ item.title }} </span>
            <span class="icon-wrap">
              <icon name="delete" />
            </span>
            <span class="icon-wrap"  >
              <icon name="edit" />
            </span>
            <span class="icon-wrap"  >
              <icon name="plus" />
            </span>
		</div>
	</div>

完整代码如下:

	<a-tree :treeData="testData">
        <span slot="switcherIcon" class="icon-plus"></span>
        <template slot="custom" slot-scope="item">
          <!-- 如果是新节点 -->
          <span v-if="item.isNewItem">
            <input type="text" class="editInput" v-model="item.name" />
            <span class="tree-cancle_icon edit-require_icon">
              <a-icon type="close-circle" />
            </span>
            <span class="tree-save_icon edit-require_icon">
              <a-icon type="check-circle" />
            </span>
          </span>
          <div v-else>
            <!-- 编辑时展示输入框 -->
            <div v-if="item.isEdit">
              <input type="text" v-model="item.title" class="editInput" />
              <span class="tree-cancle_icon edit-require_icon">
                <a-icon type="close-circle" />
              </span>
              <span class="tree-save_icon edit-require_icon">
                <a-icon type="check-circle" />
              </span>
            </div>
            <!-- 否则展示原来的节点信息 -->
            <div v-else>
              <span class="node-title">{{ item.title }} </span>
              <span class="icon-wrap">
                <icon name="delete" />
              </span>
              <span class="icon-wrap">
                <icon name="edit" />
              </span>
              <span class="icon-wrap">
                <icon name="plus" />
              </span>
            </div>
          </div>
        </template>
      </a-tree>


posted @ 2020-07-15 18:50  miku561  阅读(13042)  评论(5编辑  收藏  举报