<template>
<el-select
v-model="selectKey"
multiple
placeholder="请选择"
:popper-append-to-body="true"
collapse-tags
clearable
:style="styles"
@remove-tag="removetag"
@clear="clearall"
>
<el-option :value="selectTree" class="setstyle" disabled>
<el-tree
:ref="`tree_${id}`"
:data="options"
:props="defaultProps"
show-checkbox
:check-strictly="false"
:expand-on-click-node="true"
node-key="id"
:check-on-click-node="false"
@check="handleNodeClick"
/>
</el-option>
</el-select>
</template>
<script>
import { flatten } from '@/utils/ArrayUtils'
export default {
props: {
options: {
type: Array,
default() {
return []
}
},
id: {
type: String,
default: ''
},
value: {
type: [Array, String],
default() {
return []
},
required: true
},
styles: {
type: String,
default: ''
}
},
emit: ['on-change'],
data() {
return {
selectKey: this.value,
selectTree: [],
defaultProps: {
children: 'children',
label: 'label'
}
}
},
computed: {
optionsFlatten() {
return flatten(this.options)
}
},
watch: {
value(newVal) {
this.selectKey = newVal
},
selectKey(newVal, oldVal) {
if (newVal !== oldVal) {
this.$emit('input', this.selectKey)
this.$emit('on-change')
}
}
},
mounted() {
if (this.value.length !== this.selectTree.length) {
this.keepState()
}
},
updated() {
if (this.value.length !== this.selectTree.length) {
this.keepState()
}
},
methods: {
handleNodeClick() {
const datalist = this.$refs[`tree_${this.id}`].getCheckedNodes()
this.selectTree = []
this.value = []
datalist.forEach(item => {
if (!item.children) {
this.selectTree.push({ id: item.id, label: item.label })
this.value.push(item.label)
}
})
},
removetag() {
this.selectTree.splice(0, 1)
this.$nextTick(() => {
this.$refs[`tree_${this.id}`].setCheckedNodes(this.selectTree)
})
},
clearall() {
this.selectTree = []
this.$nextTick(() => {
this.$refs[`tree_${this.id}`].setCheckedNodes([])
})
},
// 当value与selectTree不一致时,强行将value的值赋给selectTree,注id一定要与初始options一致
keepState() {
this.selectTree = this.optionsFlatten.filter(
item => this.value.includes(item.label) && !item.children
)
this.$nextTick(() => {
this.$refs[`tree_${this.id}`].setCheckedNodes(this.selectTree)
})
}
}
}
</script>
<style lang="scss" scoped>
.setstyle {
min-height: 200Px;
padding: 0 !important;
margin: 0;
overflow: auto;
cursor: default !important;
::v-deep .el-tree-node__label {
font-size: 14Px;
}
}
</style>
基于el-select和el-tree封装:下拉多级多选
于 2022-11-29 10:26:48 首次发布