jinlin
2024-09-05 aa4a6ed94ea6861a6ce634550d2f05f528529098
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<template>
  <div class="tree_select">
    <el-select :value="valueTitle"
               ref="selectEl"
               :filterable="filterable"
               :clearable="clearable"
               @clear="clearHandle"
               :filter-method="selectFilterData"
               :size="size"
               style="height: 100%;width: 80%">
      <el-option :value="valueId" :label="valueTitle" style="height: 100%;width: 80%">
        <el-tree id="tree-option"
                 ref="selectTree"
                 :accordion="accordion"
                 :data="options"
                 :props="dataProps"
                 :node-key="dataProps.value"
                 :expand-on-click-node="false"
                 :default-expanded-keys="defaultExpandedKey"
                 :filter-node-method="filterNode"
                 @node-click="handleNodeClick">
        </el-tree>
      </el-option>
    </el-select>
  </div>
</template>
 
<script>
 
export default {
  name: 'SelectTree',
  props: {
    /* 配置项 */
    dataProps: {
      type: Object,
      default: () => {
        return {
          value: 'id', // ID字段名
          label: 'title', // 显示名称
          children: 'children' // 子级字段名
        }
      }
    },
    /* 选项列表数据(树形结构的对象数组) */
    options: {
      type: Array,
      default: () => {
        return []
      }
    },
    /* 初始值 */
    value: {
      type: [Number, String],
      default: () => {
        return null
      }
    },
    /* 可清空选项 */
    clearable: {
      type: Boolean,
      default: () => {
        return false
      }
    },
    /* 自动收起 */
    accordion: {
      type: Boolean,
      default: () => {
        return false
      }
    },
    /**
     * 下拉选项框的大小,默认最小
     */
    size: {
      type: String,
      default: () => {
        return 'mini'
      }
    },
    // 是否可以搜索
    filterable: Boolean
  },
  data () {
    return {
      valueId: this.value, // 初始值
      valueTitle: '',
      defaultExpandedKey: []
    }
  },
  mounted () {
    this.$nextTick(function () {
      this.initHandle()
    })
  },
  methods: {
    // 初始化值
    initHandle () {
      if (this.valueId) {
        this.valueTitle = this.$refs.selectTree.getNode(this.valueId).data[this.dataProps.label] // 初始化显示
        this.$refs.selectTree.setCurrentKey(this.valueId) // 设置默认选中
        this.defaultExpandedKey = [this.valueId] // 设置默认展开
      }
      this.$nextTick(() => {
        const scrollWrap = document.querySelectorAll('.el-scrollbar .el-select-dropdown__wrap')[0]
        const scrollBar = document.querySelectorAll('.el-scrollbar .el-scrollbar__bar')
        scrollWrap.style.cssText = 'margin: 0px; max-height: none; overflow: hidden;'
        scrollBar.forEach(ele => {
          ele.style.width = 0
        })
      })
    },
    // 切换选项
    handleNodeClick (node) {
      this.valueTitle = node[this.dataProps.label]
      this.valueId = node[this.dataProps.value]
      this.$emit('getValue', this.valueId)
      this.defaultExpandedKey = []
      // 选中后失去焦点,隐藏下拉框
      this.$refs.selectEl.blur()
      // 把数据还原
      this.selectFilterData('')
    },
    /**
     * 下拉框搜索
     */
    selectFilterData (val) {
      this.$refs.selectTree.filter(val)
    },
    /**
     * 过滤节点
     */
    filterNode (value, data) {
      if (!value) return true
      return data.label.indexOf(value) !== -1
    },
    // 清除选中
    clearHandle () {
      this.valueTitle = ''
      this.valueId = null
      this.defaultExpandedKey = []
      this.clearSelected()
      this.$emit('getValue', null)
    },
    /* 清空选中样式 */
    clearSelected () {
      const allNode = document.querySelectorAll('#tree-option .el-tree-node')
      allNode.forEach((element) => element.classList.remove('is-current'))
    }
  },
  watch: {
    /**
     * 监听绑定的值变化
     */
    value () {
      this.valueId = this.value
      this.initHandle()
    }
  }
}
</script>
 
<style scoped>
 
</style>