ant-design-vue tree树添加节点默认选上(有添加编辑删除)

<div>
  <a-tree
        :tree-data="treeData"
        show-icon
        :expanded-keys="expandedKeys"
        :selectedKeys="selectedKeys"
        @select="handleSelected"
        draggable
        @drop="onDrop">
    <a-icon slot="apartment" type="apartment" style="color:#1890ff" />
    <!-- <a-icon slot="file-text" type="file-text" /> -->
    <i slot="file-text" class="iconfont icon-area" />
    <template slot="custom" slot-scope="item">
      <span>{{ item.title }}</span>
      <span class="but_operation">
        <span class="but_type iconfont icon-add-k" @click="()=> openModal(item,'1')"></span>
        <span class="but_type iconfont icon-edit" style="right:120px;" @click="()=> openModal(item,'2')"></span>
        <span class="but_type iconfont icon-delete" @click="(e)=> remove(item)"></span>
      </span>
      <!-- <span class="but_ipt" v-if="visible">
        <a-input />
      </span> -->
    </template>
  </a-tree>
  <!--添加/编辑-->
  <a-modal
            :width="300"
             :maskClosable="false"
             :visible="checkVisible"
             @cancel="cancel"
             :title="modalTitle"
             :destroyOnClose="true"
             :mask="false">
      <a-input v-model="textInfo" placeholder="请输入区域" />
    <template slot="footer">
      <a-button type="primary" @click="append">确定</a-button>
      <a-button @click="cancel">取消</a-button>
    </template>
  </a-modal>
</div>
<script>
import { Tree, Icon } from 'ant-design-vue'
export default {
  components: {
    ATree: Tree,
    // ADirectoryTree: Tree.Directory,
    // ATreeNode: Tree.Node,
    AIcon: Icon
  },
  data () {
    return {
treeData: [
        {
          title: '全部',
          key: '0-0',
          slots: { icon: 'apartment' },
          children: [
            {
              title: '德风石化有限公司',
              key: '0-0-0',
              slots: { icon: 'apartment' },
              children: [
                {
                  title: '公共工程',
                  key: '0-0-0-0',
                  slots: { icon: 'apartment' },
                  children: [
                    { title: '中心控制室', key: '0-0-0-0-0', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] },
                    { title: '辅料管区', key: '0-0-0-0-1', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] },
                    { title: 'PSA伐区', key: '0-0-0-0-2', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] },
                    { title: '导热油房区', key: '0-0-0-0-3', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] },
                    { title: '甲醇裂解区', key: '0-0-0-0-4', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] },
                    { title: '机柜间', key: '0-0-0-0-5', scopedSlots: { icon: 'file-text', title: 'custom' }, children: [] }
                  ]
                },
                { title: '污水处理站', key: '0-0-0-1', scopedSlots: { icon: 'apartment' } }
              ]
            }
            // { title: 'leaf', key: '0-0-1', scopedSlots: { icon: 'apartment' } }
          ]
        }
      ],
      modalTitle: '',
      modalIndex: '',
      checkVisible: false,
      visible: false, // 是否显示输入框
      expandedKeys: [],
      datas: [], // 暂存的自己及父级的id 层级数组 例如:[爷爷级Id, 父级Id, 自己Id]
      appendData: '', // 添加的数据
      editData: '', // 编辑的数据
      textInfo: '', // 输入的区域
      isCheck: false, // 是否点击编辑新增删除
      selectedKeys: ['0-0-0'] // 默认展开父节点
    }
  },
  methods: {
    handleSelected (keys, info) {
      // console.log('selected', keys, info)
      // console.log('点击文字:', info.node.eventKey)
      if (!this.isCheck) {
        const itemKey = info.node.eventKey
        if (this.expandedKeys.length > 0) {
          if (this.expandedKeys.includes(itemKey)) {
            this.expandedKeys.splice(this.expandedKeys.indexOf(itemKey), 1)
          } else {
            this.expandedKeys = [...this.expandedKeys, itemKey]
          }
        } else {
          this.expandedKeys = [itemKey]
        }
        this.selectedKeys = []
        this.selectedKeys.push(itemKey)
      }
    },
    onCheck (checkedKeys, info) {
      // console.log('onCheck', checkedKeys, info)
    },
    // 递归查找
    searchOption (option, arr, type) {
      this.type = type
      console.log(option, arr)
      for (let s = 0; s < arr.length; s++) {
        console.log(arr[s].key, option.key)
        if (arr[s].key === option.key) {
          if (type === 'delect') {
            arr.splice(s, 1)
          } else {
            // 这是编辑数据
            this.$set(arr, s, {
              title: this.textInfo,
              key: option.key,
              scopedSlots: { icon: 'file-text', title: 'custom' },
              children: option.children
            })
          }
          break
        } else if (arr[s].children && arr[s].children.length > 0) { // 递归条件
          this.searchOption(option, arr[s].children, this.type)
        } else {
          continue
        }
      }
    },
    // 新建
    openModal (item, index) {
      console.log(item)
      this.checkVisible = true
      // eslint-disable-next-line no-undef
      index === '1' ? this.modalTitle = '添加区域' : this.modalTitle = '编辑区域'
      this.appendData = item
      this.modalIndex = index
      this.isCheck = true
    },
    // 添加/编辑
    append () {
      if (this.modalIndex === '1') {
        this.selectedKeys = []
        this.defaultExpanded = []
        const newChild = {
          title: this.textInfo,
          key: '',
          scopedSlots: { icon: 'file-text', title: 'custom' },
          children: []
        }
        if (!this.appendData.children) {
          this.$set(this.appendData, 'children', [])
          newChild.key = this.appendData.eventKey + '-' + '0'
        } else {
          if (this.appendData.children.length > 0) {
            newChild.key = this.appendData.eventKey + '-' + this.appendData.children.length - 1
          } else {
            newChild.key = this.appendData.eventKey + '-' + '0'
          }
        }
        this.appendData.children.push(newChild)
        this.selectedKeys.push(newChild.key)
        this.expandedKeys = [...this.expandedKeys, this.appendData.eventKey]
        this.checkVisible = false
      } else {
        // this.appendData.title = this.textInfo
        this.searchOption(this.appendData, this.treeData, 'edit')
        this.checkVisible = false
      }
      this.textInfo = ''
      this.isCheck = false
    },
    // 删除
    remove (item) {
      this.isCheck = true
      this.$confirm({
        title: '您确定删除该条数据吗?',
        okText: '是',
        okType: 'danger',
        cancelText: '否',
        onOk: async () => {
          this.searchOption(item, this.treeData, 'delect')
          this.isCheck = false
        }
      })
    },
    // 递归 获得自己的层级id数组
    getItemAndParentsIdArr (arr, key) {
      for (let i = 0; i < arr.length; i++) {
        if (arr[i].key === key) {
          this.datas.push(arr[i])
          return true
        } else {
          if (
            arr[i].children &&
            this.getItemAndParentsIdArr(arr[i].children, key)
          ) {
            this.datas.push(arr[i])
            return true
          }
        }
      }
    },
    // 获得自己的父级id
    getFirstParentId (strings, key) {
      const stringsArr = strings.split('/')
      const index = stringsArr.indexOf(key.toString())
      let parenId
      if (index !== 0) {
        parenId = stringsArr[index - 1]
      } else {
        parenId = stringsArr[index]
      }
      return parenId
    },
    onDrop (info) {
      console.log('拖动完成:', info)
      const dropKey = info.node.eventKey // 目标节点的id
      const dragKey = info.dragNode.eventKey // 拖拽节点的id
      const dropPos = info.node.pos.split('-')
      const dropPosition =
        info.dropPosition - Number(dropPos[dropPos.length - 1])
      const loop = (data, key, callback) => {
        data.forEach((item, index, arr) => {
          if (item.key === key) {
            return callback(item, index, arr)
          }
          if (item.children) {
            return loop(item.children, key, callback)
          }
        })
      }
      const data = [...this.treeData]

      // Find dragObject
      let dragObj

      // 如果拖动到内部
      if (!info.dropToGap) {
      } else if (
        (info.node.children || []).length > 0 && // Has children
        info.node.expanded && // Is expanded
        dropPosition === 1 // On the bottom gap
      ) {
      } else {
        // 获得拖拽节点的层级id数组 this.datas
        this.getItemAndParentsIdArr(data, dragKey)
        const dragKeyString = this.datas
          .reverse()
          .map((v, i) => {
            return v.key
          })
          .join('/')

        // 拖拽节点父级id
        const dragKeyParentId = this.getFirstParentId(dragKeyString, dragKey)
        /**
         * --------------------------------分割线---------------------------------------
         */
        // 获得目标节点的层级id数组 this.datas
        this.getItemAndParentsIdArr(data, dropKey)
        const dropKeyString = this.datas
          .reverse()
          .map((v, i) => {
            return v.key
          })
          .join('/')

        // 目标节点父级id
        const dropKeyParentId = this.getFirstParentId(dropKeyString, dropKey)
        /**
         * --------------------------------分割线---------------------------------------
         */
        // 只允许在同父级id下进行拖动
        if (dragKeyParentId === dropKeyParentId) {
          loop(data, dragKey, (item, index, arr) => {
            arr.splice(index, 1)
            dragObj = item
          })
          let ar
          let i
          loop(data, dropKey, (item, index, arr) => {
            ar = arr
            i = index
          })
          if (dropPosition === -1) {
            ar.splice(i, 0, dragObj)
          } else {
            ar.splice(i + 1, 0, dragObj)
          }
          this.treeData = data
        }
      }
    },
    cancel () {
      this.checkVisible = false
      this.isCheck = false
    }
  }
}
</script>

全局css修改

/*全局修改a-tree样式——开始*/
.ant-tree {
  position: relative;
}
.ant-tree > li span.ant-tree-node-content-wrapper::before, 
.ant-tree .ant-tree-child-tree > li span.ant-tree-node-content-wrapper::before{
  position: absolute;
    right: 0;
    left: 0;
    height: 24px;
    -webkit-transition: all 0.3s;
    transition: all 0.3s;
    content: '';
}
.ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected::before{
  background: rgba(173, 224, 251, 0.4);
}
.ant-tree li .ant-tree-node-content-wrapper:hover {
  background-color: transparent;
  color: #000;
}
.ant-tree li .ant-tree-node-content-wrapper:hover .but_operation {
  opacity: 1;
 }
.ant-tree li .ant-tree-node-content-wrapper:hover.ant-tree-node-content-wrapper-normal::before,
.ant-tree li .ant-tree-node-content-wrapper:hover.ant-tree-node-content-wrapper::before{
  background: rgba(173, 224, 251, 0.4);
  color: #000;
}
.ant-tree li .ant-tree-node-content-wrapper.ant-tree-node-selected{
  background: transparent;
}
.ant-tree > li span.ant-tree-node-content-wrapper.ant-tree-node-selected {
  color: #000;
  background: transparent;
}
/*全局修改a-tree样式——结束*/

 

原文地址:https://www.cnblogs.com/bertha-zm/p/14982250.html