使用el-select和el-tree结合-创建下拉树形分类选择器组件

原创
2023/10/18 17:23
阅读数 21
  • 使用方法
<org-select-tree v-model="form.deptId" @change="changeDept" :endOrgSort="3" :disabledNodeOrgSort="3"  :startNode2="form.orgId" isAll :showCheckbox="true" :disabled="!form.orgId"/>
  • 代码
<template>
  <div class="org-select-tree-box">
    <el-select
        ref="select"
        v-model="selectValue"
        :multiple="showCheckbox"
        :disabled="disabled"
        :placeholder="placeholder"
        :filterable="false"
        :clearable="clearable"
        @change="changed"
        @remove-tag="removeTag"
        @clear="clearAll"
        collapse-tags>
        <el-option v-for="v in selectRows" :key="v.id" :value="v.orgId" :label="v.orgName" style="display:none"></el-option>
        <el-option :value="selectValue" :label="selectLabel"  disabled style="height: auto;background-color: #FFFFFF;">
        <div class="option-box">
            <el-input placeholder="输入关键字进行过滤" v-model="filterText">
                <el-button slot="append" icon="el-icon-search" />
            </el-input>

            <el-tree
                ref="tree"
                class="filter-tree"
                :data="treeData"
                :props="treeProps"
                :node-key="nodeKey"
                :default-expand-all="false"
                :expand-on-click-node="false"
                :show-checkbox="showCheckbox"
                :check-strictly="checkStrictly"
                :filter-node-method="filterNode"
                @node-click="nodeClick"
                @check-change="handleNodeClick">
            </el-tree>
        </div>
        </el-option>
    </el-select>
  </div>
</template>

<script>
export default {
  name: 'org-select-tree', // 下拉选择单位
  props: {
    isAll: {
      type: Boolean
    }, // 是否全部数据,false只显示登陆人可以查看的单位
    clearable: {
      type: Boolean, default: true
    }, // 是否课清空
    showCheckbox: {
      type: Boolean
    }, // 是否多选框,为true时多选,绑定值为数组
    checkStrictly: {
      type: Boolean, default: true
    }, // 是否多选框
    disabled: {
      type: Boolean
    }, // 是否禁用
    placeholder: {
      type: String
    }, // 默认提示
    nodeKey: {
      type: String, default: 'orgId'
    }, // tree 的node-key
    startOrgId: {
      type: [String, Number]
    }, // 树修剪 - 从哪一个节点开始显示树结构,比如从orgId=17为办公室,就显示办公室的树结构
    startOrgSort: {
      type: [String, Number]
    }, // 树修剪 - 从哪一层级开始显示树结构,比如orgSort=3的为单位级,就从单位级开始显示树结构
    endOrgSort: {
      type: [String, Number]
    }, // 树修剪 - 最深显示到哪一层,比如orgSort=3的为单位级,则只显示到单位级
    disabledNodeOrgSort: {
      type: [String, Number]
    }, // 树修剪 - 多选时 只允许选择哪一层,比如只能选择orgSort=3的单位级,则其他层级都禁用选择
    value: {
      type: [String, Number, Array]
    }, // 绑定值
    defaultTreeProps: { type: Object, default: () => { return {} } } // tree props
  },
  data() {
    return {
      orgList: [],
      treeData: [],
      selectValue: '',
      selectLabel: '',
      selectRows: [],
      filterText: '',
      treeProps: {},
      defaultTreeProps2: {
        children: 'children',
        label: 'orgName',
        disabled: 'disabled',
        value: 'orgId'
      }
    }
  },
  watch: {
    value: {
      immediate: true,
      handler(newV) {
        this.selectValue = newV
        if (newV) {
          this.$nextTick(() => {
            if (this.showCheckbox) {
              this.selectRows = this.orgList.filter(v => newV.includes(v.orgId))
              this.$refs.tree.setCheckedNodes(this.selectRows)
            } else {
              const row = this.orgList.find((v) => v.orgId === newV)
              this.selectLabel = row && row.orgName
            }
          })
        } else {
          this.selectLabel = ''
        }
      }
    },
    selectValue(e) {
      this.$emit('input', e)
    },
    filterText(val) {
      this.$refs.tree.filter(val)
    },
    startOrgId: {
      immediate: true,
      handler() {
        this.init()
      }
    }

  },
  computed: {
    orgTreeAllData() {
      return window.vm.$store.state.user.orgTreeAllData
    },
    orgTreeData() {
      return window.vm.$store.state.user.orgTreeData
    },
    orgTreeAllDataList() {
      return window.vm.$store.state.user.orgTreeAllDataList
    },
    orgTreeDataList() {
      return window.vm.$store.state.user.orgTreeDataList
    }
  },
  created() {
    this.init()
  },
  methods: {
    init() {
      if (this.isAll) {
        this.treeData = this.orgTreeAllData
        this.orgList = this.orgTreeAllDataList
      } else {
        this.treeData = this.orgTreeData
        this.orgList = this.orgTreeDataList
      }
      this.treeProps = Object.assign({}, this.defaultTreeProps2, this.defaultTreeProps)

      // ---------  下面几种对树的修剪  -------------

      // 最深显示到哪一层,比如orgSort=3的为单位级,则只显示到单位级
      if (this.endOrgSort) {
        this.getTreeDataByEndOrgSort(this.treeData)
      }

      // 从哪一层级开始显示树结构,比如orgSort=3的为单位级,就从单位级开始显示树结构
      if (this.startOrgSort) {
        const newTreeData = []
        this.getTreeDataByOrgSort(this.treeData, newTreeData)
        this.treeData = newTreeData
      }

      // 从哪一个节点开始显示树结构,比如从orgId=17为办公室,就显示办公室的树结构
      if (this.startOrgId) {
        this.getTreeDataByOrgId(this.treeData)
      }

      // 树修剪 - 只允许选择哪一层,比如只能选择orgSort=3的单位级,则其他层级都禁用选择
      if (this.disabledNodeOrgSort) {
        this.getTreeDataByDisabledNodeOrgSort(this.treeData)
      }
    },

    // 最深显示到哪一层,比如orgSort=3的为单位级,则只显示到单位级
    getTreeDataByEndOrgSort(treeData) {
      treeData.forEach(row => {
        if (row.orgSort >= this.endOrgSort) {
          row.children = []
        }
        if (row.children && row.children.length > 0) {
          this.getTreeDataByEndOrgSort(row.children)
        }
      })
    },

    // 从哪一层级开始显示树结构,比如orgSort=3的为单位级,就从单位级开始显示树结构
    getTreeDataByOrgSort(treeData, newTreeData) {
      treeData.forEach(row => {
        if (row.orgSort == this.startOrgSort) {
          newTreeData.push(row)
        }
        if (row.children && row.children.length > 0) {
          this.getTreeDataByOrgSort(row.children, newTreeData)
        }
      })
    },

    // 获取新树的数据,从orgId=this.startOrgId开始
    getTreeDataByOrgId(treeData) {
      for (let index = 0; index < treeData.length; index++) {
        const row = treeData[index]
        if (row.orgId == this.startOrgId) {
          this.treeData = [row]
          return
        }
        if (row.children && row.children.length > 0) {
          this.getTreeData(row.children)
        }
      }
    },

    // 树修剪 - 只允许选择哪一层,比如只能选择orgSort=3的单位级,则其他层级都禁用选择
    getTreeDataByDisabledNodeOrgSort(treeData) {
      treeData.forEach(row => {
        row.disabled = row.orgSort != this.disabledNodeOrgSort
        if (row.children && row.children.length > 0) {
          this.getTreeDataByDisabledNodeOrgSort(row.children)
        }
      })
    },

    filterNode(value, data) {
      if (!value) return true
      return data[this.treeProps.label].indexOf(value) !== -1
    },
    changed(e) {
      const row = this.orgList.find((v) => v.orgId === e)
      this.$emit('change', row)
    },
    // 节点被点击时的回调
    nodeClick(e) {
      if (!this.showCheckbox) {
        this.changed(e.orgId)
        this.selectValue = e.orgId
        this.selectLabel = e.orgName
        this.$refs.select.blur()
      }
    },
    // 多选框被选中回调
    handleNodeClick() {
      const rows = this.$refs.tree.getCheckedNodes()
      this.selectValue = rows.map(v => v.orgId)
      this.selectRows = rows
      this.$emit('change', rows)
    },
    // 删除选中项
    removeTag() {
      this.selectRows.splice(0, 1)
      this.$nextTick(() => {
        this.$refs.tree.setCheckedNodes(this.selectRows)
      })
    },
    // 删除全部选中项
    clearAll() {
      this.selectRows = []
      this.$nextTick(() => {
        this.$refs.tree.setCheckedNodes([])
      })
    }

  }
}

</script>

<style>
.option-box {
padding: 0 !important;
margin: 0;
overflow: auto;
cursor: default !important;
}
</style>

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部