<template>
<!--
v-model的值(selectKey)为当前被选中的el-option的 value 属性值
-->
<el-select
v-model="selectKey"
multiple
placeholder="请选择"
:popper-append-to-body="true"
:collapse-tags='isShowMultipleTags'
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 '@/views/component/planTemplateMangement/utils/index.js'
export default {
props: {
// 多选时是否将选中值按文字的形式展示
isShowMultipleTags:{
type: Boolean,
default: true
},
options: {
type: Array,
default() {
return []
}
},
// 用于ref
id: {
type: String,
default: ''
},
// 父组件选中的值,就是用于回显
echoValue: {
type: [Array, String],
default() {
return []
},
required: true
},
// el-select样式
styles: {
type: String,
default: ''
}
},
emit: ['on-change'],
data() {
return {
selectKey: this.echoValue,
selectTree: [], // el-select选中的值
defaultProps: {
children: 'children',
label: 'label'
}
}
},
computed: {
optionsFlatten() {
return flatten(this.options)
}
},
watch: {
echoValue(newVal) {
this.selectKey = newVal
},
selectKey(newVal, oldVal) {
if (newVal !== oldVal) {
this.$emit('input', this.selectKey)
this.$emit('on-change')
}
}
},
mounted() {
if (this.echoValue.length !== this.selectTree.length) {
this.keepState()
}
},
updated() {
if (this.echoValue.length !== this.selectTree.length) {
this.keepState()
}
},
methods: {
handleNodeClick() {
const datalist = this.$refs[`tree_${this.id}`].getCheckedNodes()
this.selectTree = []
this.selectKey = []
datalist.forEach(item => {
if (!item.children) {
this.selectTree.push({ id: item.id, label: item.label })
this.selectKey.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
// )
// 通过node设置 setCheckedNodes 设置目前勾选的节点
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>
JS文件
// 将包含children对象的多维数组扁平化
export const flatten = arr => {
const stack = [...arr];
const result = [];
while (stack.length) {
const next = stack.pop();
if (Array.isArray(next.children)) {
stack.push(...next.children);
}
result.push(next);
}
return result;
}