vue2-org-tree 基於VUE的部門組織架構組件,增刪節點實現


本文所用組件傳送門:vue-org-tree  

本文基於antd (其他前端組件框架操作基本都類似的: iview,elementui,boostrap-vue...)

當然,github上還有其他類似的組件,實現方法各有不同,顯示效果也有差異,但都是很方便的組件。

看到網上有很多相關的使用教程,github上也寫得很清楚,這里恕不在重復,本文主要實現增刪節點。

場景:我們通常展示部門樹的時候,簡單的直接就是一個下拉框展示,為了顯示明顯,可能會使用一些樹。
   

圖片截至:(antd vue文檔)

但是簡單的樹形已經很難滿足變態的需求了。盡管做到tree已經很自然的顯示了組織架構關系了。這個時候就需要更好看,更直接的顯示方式了。

先預覽一下vue2-org-tree 組件的樣式:

 

顯示效果非常不錯了。層級關系清晰明了,而且支持節點開閉,手動配置樣式等功能。

立馬上手,照着官方案例搞了一個,嗯嗯,很不錯,確實是大佬們想要的。

 把玩一番,頗為得意,很輕松的解決了煩人的需求。果然天道酬勤,報應不爽啊,才懶一會兒,就被潑了涼水,因為我發現一個很讓人絕望的問題。這個組件不支持擴展子節點。

是的,它只支持你把數據傳進來,然后渲染出效果。然后點兩下開關,橫排豎排顯示,沒了。。。。。。剛開始認為這個組件不夠全面,是的,至少支持增刪的話。但是現在的前端開發,完全組件式開發。你需要飛機,就給你飛機,但是發動機,座位,機組人員,配套設施,都需要你自己去添加,因為你無法開發出一個完全適配所有配置的組件,如果你開發出來了,首先很牛,但是這個組件的庫一定非常巨大,你需要適配的各種設施都在你的庫里,你需要下載半小時的庫包(雖然開玩笑,但確實庫比較大加載是很費時的)。所以大家都趨於開發出一個小巧輕便的組件

失望歸失望,研究一番,發現組件提供的API里面有自定義渲染方式的prop:renderContent 

既然支持自定義渲染方式,我傳入一個jsx會怎么樣呢?迅速找到antd的下拉菜單組件:

 附上官方源碼:

<template>
  <a-dropdown :trigger="['click']">
    <a class="ant-dropdown-link" href="#">
      Click me <a-icon type="down" />
    </a>
    <a-menu slot="overlay">
      <a-menu-item key="0">
        <a href="http://www.alipay.com/">1st menu item</a>
      </a-menu-item>
      <a-menu-item key="1">
        <a href="http://www.taobao.com/">2nd menu item</a>
      </a-menu-item>
      <a-menu-divider />
      <a-menu-item key="3">3rd menu item</a-menu-item>
    </a-menu>
  </a-dropdown>
</template>

通過鼠標點擊展開下拉菜單。點擊子菜單可以實現不同的功能。我讓每一個節點都是一個下拉菜單,不就可以了嗎?把上面的代碼改寫成jsx形式,並寫入renderContent 方法里,記得定義組件renderContent 屬性哦。

 renderContent (h, data) {
      return (<span><a-dropdown trigger={['click']}>
        <a>{data.title}</a>
        <a-menu slot="overlay" onclick={(key) => this.onClick(key, data)}>
          <a-menu-item v-show={data.level !== 0} key={'add'}>添加同級部門</a-menu-item>
          <a-menu-item key={'addChild'}>添加下級部門</a-menu-item>
          <a-menu-item key={'edit'}>修改部門</a-menu-item>
          <a-menu-item key={'del'} >刪除部門</a-menu-item ></a-menu ></a-dropdown ></span >)
    }

h不解釋啦,就是jsx對象。data是我的數據,title是名稱。onclick就是a元素的js事件,這里傳遞了下拉菜單的key,並用箭頭函數指向自定義的onClick函數。

 onClick (keyObj, node) {
      if (keyObj.key === 'del') {
        if (node.children && node.children.length > 0) {
          this.$message.info('當前部門存在子部門,請先刪除子部門')
        } else {
          this.$http.get('/rdDept/del', { params: { id: node.value } })
            .then(res => {
              if (res.success && res.data) {
                this.$message.success('刪除成功')
                this.loadTree()
              } else {
                this.$message.error(res.errorMessage)
              }
            })
        }
      } else {
        this.$refs.modifyDept.showModal(keyObj.key, node)
      }
    }

onclick里只處理了刪除操作,並且存在子節點,就不進行刪除。

先看下目前的效果:

視圖完全沒問題。操作下拉菜單:

 

正確響應。

寫到這里,已經實現刪除操作了。新增,修改操作其實已經呼之欲出了,定義一個輸入框彈出層,這里就不貼具體代碼了。

顯示效果如下:

 現在我們回到onClick方法的最后一行代碼:

  this.$refs.modifyDept.showModal(keyObj.key, node)

modifyDept是我新建的組件,showModal是組件的方法,key就是組件的下拉菜單key,node就是當前節點。我們來看下showModal方法:

 showModal (key, data) {switch (key) {
          case 'edit':
            this.setDept(data.title, data.value, data.parentId, data.level, `修改[${data.title}]`, data.identity)
            break
          case 'add':
            this.setDept('', -1, data.parentId, data.level, `添加同級部門[${data.title}]`, data.identity)
            break
          case 'addChild':
            data.identity = data.identity === '' ? data.value : `${data.identity}:${data.value}`
            this.setDept('', -1, data.value, data.level + 1, `添加下級部門[${data.title}]`, data.identity)
            break
          default:
            this.setDept('', -1, -1, 0, '添加研發部門', '')
            break
        }
    },
    setDept (name, id, parentId, level, title, identity) {
      this.form.setFieldsValue({ deptName: name })
      this.params.id = id
      this.params.parentId = parentId
      this.params.level = level
      this.params.thisIdentity = identity
      this.title = title
    }

根據傳遞過來的key確定操作,setDept方法設置當前操作的部門的樹形。

this.params對象是傳遞到后台的對象。就是你想操作的對象。

this.form.setFieldsValue({ deptName: name }) 該方法來自antd form表單api,設置輸入框deptName 的值。
輸入框代碼如下:
<a-form :form="form">
  <a-form-item :label-col="{ span: 0 }" :wrapper-col="{ span: 24 }">
    <a-input v-decorator="['deptName',{rules: [{ required: true, message: '請輸入研發部門' }]}]" />
  </a-form-item>
</a-form>

接下來,你只需要寫一個form的提交操作。把params對象傳遞了后台,然后由后台進行更新插入操作。然后刷新你的部門樹,就實現增刪功能了。

關鍵操作其實還是在jsx那段代碼。你可以用jsx 做到你想要的任何效果。

The end!

 


免責聲明!

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



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