【vue】ant-design-vue的树结构实现节点增删改查

根据业务需要,实现树结构的节点新增编辑删除功能,主要逻辑是利用树节点的scopedSlots属性对其进行自定义改造,监听悬停事件在节点右侧出现增删改对应图标,点击图标出现弹窗表单对内容进行修改,具体代码如下:

// 模板部分
<template>
  <a-tree
     v-if="factorTreeData.length > 0"
     show-icon
     default-expand-parent
     :tree-data="factorTreeData"
     :defaultExpandAll="true"
     :autoExpandParent="true"
     :default-selected-keys="selectedKeys"
     @select="onTreeSelect">
     <template slot="custom" slot-scope="item">
       <div @mouseenter="onMouseEnter(item)" style="position: relative;">
         <span class="treeMode">
           <a-icon v-if="!item.isLeaf" :type="item.expanded ? 'folder-open' : 'folder'" />
           <a-icon type="file" v-if="item.isLeaf"/>
           <span style="margin-left: 5px">
             {{ item.title }}
           </span>
         </span>
         <a-space
           @click.stop
           v-if="mouseItemId === item.key"
           style="position: absolute; right: 5px; top: 0"
         >
           <a-button type="primary" size="small" icon="plus" @click="addTreeNode(item)" />
           <a-button type="primary" size="small" icon="edit" @click="editTreeNode(item)" />
           <a-button type="primary" size="small" icon="delete" @click="delTreeNode(item)" />
         </a-space>
       </div>
     </template>
   </a-tree>
    <a-modal
        v-drag-modal
         v-model="visible"
         :title="modalTitle"
         :destroyOnClose="true"
         @ok="handleSave"
         :width="800"
         :bodyStyle="{'height': '480px', 'overflow-y': 'auto'}"
         centered
       >
         <ItemModal ref="childModal" :formObj="formObj"/>
    </a-modal>
</template>

//js部分
<script>
	export default {
	 components: {
      ItemModal: () => import ('./item-modal') // 表单弹窗
     },
	 data () {
      	return {
      		// 树结构
	        factorTreeData: [],
	        expandedKeys: [],
	        selectedKeys: [],
	        mouseItemId: '',
	         // 弹窗
       		modalTitle: '',
            visible: false,
	        formObj: {}
      	}
      },
      mounted () {
      	this.getTreeData()
      },
      methods: {
        // 获取树(模拟数据)
       getTreeData () {
        this.factorTreeData= [
	        {
			    title: '0-0',
			    key: '0-0',
			    children: [
			      {
			        title: '0-0-0',
			        key: '0-0-0',
			        children: [
			          { title: '0-0-0-0', key: '0-0-0-0' },
			          { title: '0-0-0-1', key: '0-0-0-1' },
			          { title: '0-0-0-2', key: '0-0-0-2' },
			        ],
			      },
			      {
			        title: '0-0-1',
			        key: '0-0-1',
			        children: [
			          { title: '0-0-1-0', key: '0-0-1-0' },
			          { title: '0-0-1-1', key: '0-0-1-1' },
			          { title: '0-0-1-2', key: '0-0-1-2' },
			        ],
			      },
			    ],
			  }
		  ]
		  this.dealTreeData(this.factorTreeData || [])
		  this.selectedKeys = [this.factorTreeData.children[0].key]
          this.mouseItemId = this.factorTreeData.children[0].key
	    },
      	// 给每个节点添加自定义属性
      	dealTreeData (dataArr) {
         dataArr.forEach((el, i) => {
          el.value = el.key 
          if (el.children && el.children.length > 0) {
            el.isLeaf = false
            el.selectable = false
            el['scopedSlots'] = { title: 'custom' } 
            this.dealTreeData(el.children)
          } else {
            el.isLeaf = true
            el['scopedSlots'] = { title: 'custom' }
          }
        })
      },
      // 节点选择事件
      onTreeSelect (selectedKeys) {
      },
	  // 树鼠标悬停事件
      onMouseEnter (item) {
        this.mouseItemId = item.key
      },
      // 添加树节点
      addTreeNode (item) {
        this.formObj = {
          id: null,
          pid: item.parentId,
          name: '',
          displayOrder: '',
          status: '',
          remark: ''
        }
        this.modalTitle = '新增'
        this.visible = true
      },
      // 编辑树节点
      editTreeNode (item) {
        getTreeInfo({ id: item.id }).then(res => {
          if (res.code === 200) {
            this.formObj = {
              id: res.result[0].id,
              pid: res.result[0].pid,
              name: res.result[0].name,
              displayOrder: res.result[0].displayOrder,
              status: res.result[0].status,
              remark: res.result[0].remark
            }
            this.modalTitle = '编辑'
            this.visible = true
          }
        }).catch(err => console.log(err))
      },
      // 保存树节点
      handleSave() {},
      // 删除树节点
      delTreeNode (item) {
        const that = this
        this.$confirm({
          title: '确定要删除吗?',
          onOk () {
            delTree({ ids: item.id }).then(res => {
              if (res.code === 200) {
                that.$message.success('删除成功!')
                that.getTree() // 重新请求树数据
              } else {
                that.$message.error('删除失败!')
              }
            }).catch(err => {
              console.log(err)
              this.$message.error('删除失败!')
            })
          }
        })
      }
	}
</script>
 <style lang="less" scoped>
 // 树
    ::v-deep .ant-tree {
      li {
        padding: 1px 0;
      }

      .ant-tree-node-content-wrapper {
        width: calc(100% - 24px);
        height: 32px;
        line-height: 32px;
      }
      .treeMode {
        height: 30px;
        width: 70%;
        display: flex;
        align-items: center;
        span {
          height: 30px;
          display: inline-block;
          max-width: 80%;
          overflow: hidden;
          text-overflow: ellipsis;
          padding-right: 5px;
        }
      }
    }
    ::v-deep .ant-tree.ant-tree-directory > li span.ant-tree-node-content-wrapper::before {
      height: 32px;
    }
 </style>

示例:
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值