自定义组件
<template>
<el-select v-model="value" size="mini" style="display:block" :clearable="clearable" @clear="clearHandle">
<el-input
v-model="filterText"
size="mini"
clearable
placeholder="输入关键字进行过滤"
/>
<el-option :value="value" :label="value?valueTitle:''" class="options">
<el-tree id="tree-option" ref="selectTree" :accordion="accordion" :data="options" :props="props" :filter-node-method="filterNode" :node-key="props.value" :default-expanded-keys="defaultExpandedKey" @node-click="handleNodeClick" />
</el-option>
</el-select>
</template>
<script>
export default {
name: 'ElTreeSelect',
props: {
// 配置项
props: {
type: Object,
// eslint-disable-next-line vue/require-valid-default-prop
default: {
value: 'id', // ID字段名
label: 'title', // 显示名称
children: 'children'// 子级字段名
}
},
// 选项列表数据(树形结构的对象数组)
// eslint-disable-next-line vue/require-valid-default-prop
options: { type: Array, default: [] },
// 初始值
value: { type: String, default: null },
// title: { type: String, default: null },
// 可清空选项
clearable: { type: Boolean, default: true },
// 自动收起
accordion: { type: Boolean, default: false },
// 过滤器
filterText: { type: String, default: null }
},
data() {
return {
valueId: null,
valueTitle: '',
defaultExpandedKey: [],
parentNodes: []
// filterText: ''
}
},
watch: {
value() {
this.valueId = this.value
this.initHandle()
},
// 监听过滤查询
filterText(val) {
this.$refs.selectTree.filter(val)
}
},
mounted() {
this.valueId = this.value// 初始值
this.initHandle()
},
methods: {
// 树结构数据过滤查询
filterNode(value, data) {
if (!value) return true
return data.recName.indexOf(value) !== -1
},
// 初始化值
initHandle() {
if (this.value) {
if (this.$refs.selectTree.getNode(this.value)) {
this.valueTitle = this.$refs.selectTree.getNode(this.value).data[this.props.label] // 初始化显示
this.$refs.selectTree.setCurrentKey(this.value) // 设置默认选中
this.defaultExpandedKey = [this.value] // 设置默认展开
}
}
this.initScroll()
},
// 初始化滚动条
initScroll() {
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;'
// eslint-disable-next-line no-return-assign
scrollBar.forEach(ele => ele.style.width = 0)
})
},
// 切换选项
handleNodeClick(node, a, b, c) {
this.parentNodes = [] // 清空父级节点列表
this.getParents(this.options, a) // 调用递归函数获取父级节点
this.$emit('getParentLabel', this.parentNodes.join('/'))
// this.valueTitle = node[this.props.label]
this.valueTitle = this.parentNodes.join('/')
this.valueId = node[this.props.value]
console.log(this.options)
// this.$emit('getValue', this.valueId)
this.defaultExpandedKey = []
},
getParents(tree, node) {
if (node.parent) {
this.parentNodes.push(node.data.recName) // 将父级节点添加到列表中
this.getParents(tree, node.parent) // 递归调用获取更上一级的父级节点
} else {
this.parentNodes.reverse() // 反转数组,使得父级节点按照从上到下的顺序排列
}
},
// 清除选中
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'))
}
}
}
</script>
<style scoped>
.el-scrollbar .el-scrollbar__view .el-select-dropdown__item{
height: auto;
max-height: 230px;
padding: 0;
overflow: hidden;
overflow-y: auto;
}
.el-select-dropdown__item.selected{
font-weight: normal;
}
ul li >>> .el-tree .el-tree-node__content{
height:auto;
padding: 0 20px;
}
.el-tree-node__label{
font-weight: normal;
}
.el-tree >>> .is-current .el-tree-node__label{
color: #409EFF;
font-weight: 700;
}
.el-tree >>> .is-current .el-tree-node__children .el-tree-node__label{
color:#606266;
font-weight: normal;
}
</style>
组件引用
使用组件
<el-col :span="20" class="m-el-col">
<index1 :props="recProps" :options="recList" :value="form.homeAddrInfo" :filter-text="selectTreeTextRec" filterable @getParentLabel="getParentLabel($event)"/>
</el-col>
使用方法
getParentLabel(value) {
this.form.homeAddrInfo = value
},