elementUI implements selecttree custom drop-down box tree component

elementUI has a select component and a tree component, but there is no combination of the drop-down box and the tree component, so this time we will customize one.


renderings

insert image description here

Import components

<select-tree ref="selectTree" @treeChange="treeChangeFun" :dataArray="orgList" :value="currentValue" />

import selectTree from '@/components/selectTree.vue'
components: {
    
    
    selectTree
},
treeChangeFun (val) {
    
    
   console.log(val)
},

important point:

  • treeChange is the emit function of the subcomponent
  • dataArray is the data of the tree, in the form of a parent-child nested structure
  • value is the node id selected by default (or other keys, subject to the value defined by node-key), if there is no need to select the node by default, this parameter can also be ignored

Write component js

The source code is as follows:

<template>
    <div class="selectTree">
        <el-select class="main-select-tree" ref="selectTree" v-model="transitValue">
            <el-option v-for="item in selectOptions" :key="item.id" :label="item.name" :value="item.id" style="display: none;" />
            <el-tree class="main-select-el-tree" ref="selecteltree" :highlight-current="true" :data="dataArray" :props="defaultProps" :expand-on-click-node="false" node-key="id" @node-click="handleNodeClick" :current-node-key="currentKey" :default-expanded-keys="[value]" />
        </el-select>
    </div>
</template>
<script>
export default {
    
    
  name: 'selectTree',
  props: {
    
    
    dataArray: Array,
    value: [Number, String]
  },
  data () {
    
    
    return {
    
    
      transitValue: '',
      selectOptions: [],
      currentKey: null,
      defaultProps: {
    
    
        label: 'name',
        children: 'children'
      }
    }
  },
  computed: {
    
    
    formatData () {
    
    
      let result = []
      function getChild (item) {
    
    
        item.forEach((i, x) => {
    
    
          if (Array.isArray(i['children'])) {
    
    
            result.push(i)
            getChild(i['children'])
          } else {
    
    
            result.push(i)
          }
        })
      }
      getChild(this.dataArray)
      return result
    }
  },
  methods: {
    
    
    handleNodeClick (node) {
    
    
      this.$emit('treeChange', node)
      this.transitValue = node.id
      this.$refs.selectTree.blur()
    }
  },
  watch: {
    
    
    formatData (n) {
    
    
      if (n.length > 0) {
    
    
        this.selectOptions = n
      } else {
    
    
        this.selectOptions = []
      }
    },
    value: {
    
    
    //   immediate: true,
    //   deep: true,
      handler: function (n) {
    
    
        if (n.toString()) {
    
    
          this.$nextTick(() => {
    
    
            this.transitValue = n
            this.currentKey = this.value
            this.$refs['selecteltree'].setCurrentKey(this.currentKey)
          })
        } else {
    
    
          this.$nextTick(() => {
    
    
            this.transitValue = n
            this.currentKey = this.value
            this.$refs['selecteltree'].setCurrentKey(null)
          })
        }
      }
    }
  }
}
</script>
<style lang="less" scoped>
/deep/ .el-tree-node.is-current>.el-tree-node__content {
    
    
    color: #409EFF;
}
</style>

important point:

  • It can be seen that we normally wrap option in select, this is to rely on option to support the height of the drop-down area, set the style asdisplay:none
  • At the same time, the tree component is wrapped at the same level as the option, which is the actual effect component to be displayed.
  • transitValue is the model value of the select component, selectOptions is an array of option values, currentKey is the node selected by default during initialization, and defaultProps is the mapping object of the tree data.
  • The function of the formatData function is to convert the nested array into a one-dimensional array that is tiled into one level, which is convenient for the option component to traverse and display.
  • handleNodeClick is the click event of the tree, which triggers the emit event of the child component.
  • formatData in watch is used to detect data changes and dynamically render options.
  • The value in the watch is used to detect the value in real time to determine the selected item of the subcomponent tree (this operation is used when the component is initialized, or the parent component resets the condition, or other values ​​are not changed by directly clicking the subcomponent tree node. operation).

Guess you like

Origin blog.csdn.net/qq_35517283/article/details/130123578