antdv tree可編輯樹組件


基於 antd vue 1.7.x版本的樹結構,可自行增刪改子集。原創文章。
效果圖:

 

 源碼:

 

<template>
  <div>
    <p :class="{title, required: isRequired}">{{ title }}</p>
    <div class="content">
      <a-tree
      show-line
      :tree-data="treeSource"
      :expandedKeys="expandedData"
      @expand="handleExpand"
      >
        <a-icon slot="icon" type="carry-out" />
        <!-- 插槽名稱寫死為custom,需要傳入的treeData中需要用到自定義插槽的對象中增加scopedSlots: { title: "custom" }屬性 -->
        <template slot="custom" slot-scope="item">
          <span v-if="item.isEdit">
            <a-input ref="new" type="text" class="editInput" v-model.trim="newItem" @pressEnter="addConfirm(item)" />
            <a-icon type="close-circle" @click="addCancel(item)"/>
            <a-icon type="check-circle" @click="addConfirm(item)"/>
          </span>
          <div v-else>
            <span class="node-title">{{ item.title }}</span>
            <span class="icon-wrap">
              <a-icon type="plus" title="添加子集" @click="addItem(item)" />
            </span>
            <span class="icon-wrap">
              <a-icon type="edit" title="編輯"  @click="editItem(item)" />
            </span>
            <span class="icon-wrap">
              <a-icon type="delete" title="刪除"  @click="deleteItem(item)" />
            </span>
          </div>
        </template>
      </a-tree>
      <a-button type="primary" @click="addFirstItem">增加一級節點</a-button>
    </div>
  </div>
</template>

<script>
export default {
  name: 'treeEdit',
  props: {
    isRequired: {
      type: Boolean,
      default: true
    },
    title: {
      type: String,
      default: ''
    },
    // 樹的數據源,結構{scopedSlots: { title: "custom" },//插槽名稱寫死為custom,children:[],key:xx,title:xx,level:xx,isEdit:true}
    treeData: {
      type: Array,
      default: () => {
        return []
      }
    },
    defaultExpanded: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  data () {
    return {
      treeSource: [],
      expandedData: [],
      newItem: '',
      editFlag: false, // 記錄是否有已經處於編輯狀態的標識
      newFlag: false, // 記錄是否是新建節點,用於在cancel的時候判斷是該刪除還是恢復原樣
    }
  },
  methods: {
    handleExpand (expandedKeys) {
      this.expandedData = expandedKeys
    },
    addFirstItem () {
      if (this.editFlag) {
        this.$message.warning('已有編輯項,請先編輯完成!')
        return
      }
      this.treeSource.push({
        children: [],
        key: this.getItemNextId(),
        title: '',
        level: 1,
        scopedSlots: { title: "custom" },
        isEdit: true
      })
      this.newItem = ''
      this.editFlag = true
      this.newFlag = true
      this.$nextTick(() => {
        this.$refs.new.focus()
      })
    },
    addItem (item) {
      if (this.editFlag) {
        this.$message.warning('已有編輯項,請先編輯完成!')
        return
      }
      item.children.push({
        children: [],
        key: this.getItemNextId(),
        title: '',
        level: item.level + 1,
        scopedSlots: { title: "custom" },
        isEdit: true
      })
      this.newItem = ''
      this.editFlag = true
      this.newFlag = true
      this.expandedData.push(item.key)
      this.$nextTick(() => {
        this.$refs.new.focus()
      })
    },
    editItem (item) {
      if (this.editFlag) {
        this.$message.warning('已有編輯項,請先編輯完成!')
        return
      }
      item.isEdit = true
      this.newFlag = false
      this.editFlag = true
      this.newItem = item.title
      this.treeListItemActions(this.treeSource, item.key, 'edit', item)
      this.$nextTick(() => {
        this.$refs.new.focus()
      })
    },
    deleteItem (item) {
      if (item.children.length > 0) {
        let that = this
        this.$confirm({
          title: '操作提示',
          content: '將會刪除此節點的所有子節點,確定刪除?',
          centered: true,
          onOk () {
            that.treeListItemActions(that.treeSource, item.key, 'delete')
          },
          onCancel () {
            that.$message.info('已取消')
          }
        })
      } else {
        this.treeListItemActions(this.treeSource, item.key, 'delete')
      }
    },
    addCancel (item) {
      this.newItem = ''
      item.isEdit = false
      this.editFlag = false
      this.treeListItemActions(this.treeSource, item.key, this.newFlag ? 'delete' : 'edit', item)
    },
    addConfirm (item) {
      if (this.newItem !== null && this.newItem.trim() !== '') {
        item.title = this.newItem
        item.isEdit = false
        this.editFlag = false
        this.treeListItemActions(this.treeSource, item.key, 'edit', item)
      } else {
        this.$message.warning('不允許為空')
      }
    },
    // 獲取新節點的id(時間戳加隨機數)
    getItemNextId () {
      return (new Date().getTime() + Math.ceil(Math.random() * 10000)).toString()
    },
    // 根據id屬性從數組(樹結構)中匹配元素,執行action操作
    treeListItemActions(treeList, key, action, item) {
      if (!treeList || !treeList.length) {
        return
      }
      for (let i = 0; i < treeList.length; i++) {
        if (treeList[i].key === key) {
          if (action === 'delete') {
            treeList.splice(i, 1)
            this.$forceUpdate()
          } else if (action === 'edit') {
            treeList[i] = item
            this.$forceUpdate()
          }
          break
        }
        this.treeListItemActions(treeList[i].children, key, action, item)
      }
    },
    // 提供給調用方獲取樹的數據源的方法
    getData () {
      return this.treeSource
    }
  },
  created () {
    this.treeSource = JSON.parse(JSON.stringify(this.treeData))
    this.expandedData = JSON.parse(JSON.stringify(this.defaultExpanded))
  }
}
</script>

<style lang="less" scoped>
  .title {
    color: rgba(0, 0, 0, 0.85);
  }

  .required {
    &::before {
      display: inline-block;
      margin-right: 4px;
      color: #f5222d;
      font-size: 14px;
      font-family: SimSun, sans-serif;
      line-height: 1;
      content: '*';
    }
  }

  .content {
    margin-left: 20px;
    .icon-wrap {
      padding: 0 8px;
    }
    .editInput {
      padding: 0;
      margin-right: 5px;
      height: 24px;
    }
  }
</style>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM