Vue + elementUI は部門を選択するためのドロップダウン ツリー構造を実現し、複数選択をサポートし、検索をサポートします

Vue + elementUI は部門を選択するためのドロップダウン ツリー構造を実現し、複数選択をサポートし、検索をサポートします

<template>
  <div>
    <el-select v-model="multiple?choosedValue:choosedValue[0]" element-loading-background="rgba(0,0,0,0.8)"
               :disabled="disableFlag" @visible-change="visibleChange"
               filterable clearable collapse-tags :filter-method="filterMethod" @clear="clear" @remove-tag="removeTag"
               :multiple="multiple" ref="selectRef" v-loading="loading" style="width: 100%">
      <el-option :label="option.name" :value="option.id" v-for="option in options" :key="option.id"
                 class="optionClass"/>
      <template v-slot:empty>
        <div/>
      </template>
      <el-tree :props="treeProps" :load="loadNode" :data="treeData" :show-checkbox="multiple" @check="handleCheck"
               :expand-on-click-node="false" @node-click="chooseNode" :filter-node-method="filterNodeMethod"
               class="treeClass" ref="treeRef" :node-key="'id'" :default-checked-keys="choosedValue"/>
    </el-select>
  </div>
</template>

<script>
import {
    
    getDwxxOfTree} from "@/api/commentTable/api";

export default {
    
    
  name: "chooseUnitTree",
  props: {
    
    
    disableFlag: {
    
    
      Type: Boolean,
      required: false,
      default: false
    },
    value: {
    
    
      Type: Object,
      required: true
    },
    multiple: {
    
    
      Type: Boolean,
      required: false,
      default: false
    }
  },
  data() {
    
    
    return {
    
    
      treeProps: {
    
    
        label: 'name',
        value: 'id',
        children: 'children'
      },
      deptMap: {
    
    },
      treeData: [],
      options: [],
      loading: false,
      choosedValue: [],
      choosedOptions: [],
    }
  },
  computed: {
    
    },
  watch: {
    
    
    // choosedValue: {
    
    
    //   handler(n, o) {
    
    
    //     if (this.$refs.treeRef) {
    
    
    //       this.$refs.treeRef.filter()
    //     }
    //   },
    //   immediate: true,
    //   deep: true
    // }
  },
  mounted() {
    
    
    this.choosedValue = []
    this.getNodeData()
  },
  methods: {
    
    
    visibleChange(visible) {
    
    
      if (!visible) {
    
    
        this.$refs.treeRef.filter()
      }
    },
    removeTag(nodeId) {
    
    
      this.choosedValue = this.choosedValue.filter(item => item !== nodeId)
      this.choosedOptions = this.choosedOptions.filter(item => item.id !== nodeId)
      this.$refs.treeRef.setCheckedKeys(this.choosedValue, false)
      this.$emit('input', this.multiple ? this.choosedValue : this.choosedValue[0])
    },
    clear() {
    
    
      this.choosedValue = []
      this.choosedOptions = []
      this.$refs.treeRef.setCheckedKeys([], false)
      this.$emit('input', '')
    },
    filterMethod(keyWord) {
    
    
      this.$refs.treeRef.filter(keyWord)
    },
    filterNodeMethod(keyWord, node) {
    
    
      if (!keyWord) {
    
    
        return true
      }
      return (node.name + node.id).includes(keyWord)
    },
    init() {
    
    
      this.choosedValue = []
      if (typeof this.value === 'string') {
    
    
        this.choosedOptions.push(this.deptMap[this.value])
        this.choosedValue.push(this.value)
      } else {
    
    
        this.value.forEach(item => {
    
    
          this.choosedOptions.push(this.deptMap[item.id])
          this.choosedValue = this.value
        })
      }
    },
    getNodeData(resolve) {
    
    
      this.loading = true
      getDwxxOfTree().then(dwxxResult => {
    
    
        // dwxxResult.data :
        // [{
    
    
        //   id  : "123456"
        //   name : "xx集团"
        //   pid : "000000"
        // }]
        this.loading = false
        if (dwxxResult.data) {
    
    
          this.options = dwxxResult.data
          const rootDept = []
          this.deptMap = {
    
    }
          for (let deptInfo of dwxxResult.data) {
    
    
            this.deptMap[deptInfo.id] = deptInfo
          }
          for (let deptInfo of dwxxResult.data) {
    
    
            if (!this.deptMap[deptInfo.pid]) {
    
    
              rootDept.push(deptInfo)
            }
          }
          if (resolve) {
    
    
            resolve(rootDept)
          }
        } else {
    
    
          if (resolve) {
    
    
            resolve([])
          }
        }
        this.init()
        this.createTree(dwxxResult.data)
      })
    },
    createNodeChildren(node) {
    
    
      let children = []
      for (let deptId in this.deptMap) {
    
    
        let tmpNode = this.deptMap[deptId]
        if (tmpNode.pid === node.id) {
    
    
          children.push(this.createNodeChildren(tmpNode))
        }
      }
      node.children = children
      return node
    },
    createTree() {
    
    
      this.treeData = []
      for (let deptId in this.deptMap) {
    
    
        let node = this.deptMap[deptId]
        if (!this.deptMap[node.pid]) {
    
    
          this.treeData.push(this.createNodeChildren(node))
        }
      }
    },
    loadNode(node, resolve) {
    
    
      if (node.level === 0) {
    
    
        this.getNodeData(resolve)
      } else {
    
    
        const children = []
        for (let deptId in this.deptMap) {
    
    
          if (this.deptMap[deptId].pid === node.data.id) {
    
    
            children.push(this.deptMap[deptId])
          }
          resolve(children)
        }
      }
    },
    handleCheck(data, currentData) {
    
    
      this.choosedOptions = this.multiple ? [data] : currentData.checkedNodes // this.$refs.treeRef.getCheckedNodes(false, false)
      if (this.choosedOptions.length > 0) {
    
    
        const tempMap = {
    
    }
        this.choosedOptions.forEach(op => {
    
    
          tempMap[op.id] = op
        })
        let tmpOps = []
        this.choosedOptions.forEach(op => {
    
    
          if (!tempMap[op.pid]) {
    
    
            tmpOps.push(op)
          }
        })
        this.choosedOptions = tmpOps
        this.choosedValue = this.choosedOptions.map(item => item.id)
      } else {
    
    
        this.choosedValue = []
      }
      this.$emit('input', this.multiple ? this.choosedValue : this.choosedValue[0])
    },
    chooseNode(data) {
    
    
      this.choosedOptions = [data]
      this.choosedValue = [data.id]
      this.$emit('input', data.id)
      this.$refs.selectRef.visible = false
    }
  }
}
</script>

<style scoped lang="scss">
.optionClass {
    
    
  display: none;
}

.treeClass {
    
    
  background: transparent;
  margin: 10px;
}
</style>

おすすめ

転載: blog.csdn.net/geshi201028/article/details/132151373