效果图
代码 用的是vue3写法,喜欢用vue2的同学可以自行修改下。
父组件
<select-tree :treeData="treeData" :labelId="ruleForm.parentId"
@selectTreeVal="selectTreeFather"></select-tree>
// 接收选中的数据
const selectTreeFather =(params)=> {
console.log('父组件获取树数据', params)
diaData.ruleForm.parentRealVal = params
}
子组件
<template>
<div>
<el-select v-model="label"
ref="selectRef"
multiple
@remove-tag="removeTag"
placeholder="请选择">
<template #empty>
<div class="selectClose">
<i class="el-icon-close" @click="closeSelect"></i>
</div>
<div class="selectTree">
<el-tree
:data="treeData"
:props="propsDefault"
show-checkbox
check-strictly
:node-key="nodeKey"
check-on-click-node
default-expand-all
ref="treeListDept"
:expand-on-click-node="false"
@check-change="(data, data2) => checkChangeTree(data, data2)">
</el-tree>
</div>
</template>
</el-select>
</div>
</template>
<script>
import { reactive, toRefs, ref, onMounted, watch, nextTick } from 'vue'
export default {
props: {
// 编辑时获取真实值映射
labelId: {
type: Array,
default: () => []
},
// id映射值
idVal: {
type: String,
default: 'id'
},
// label映射值
labelVal: {
type: String,
default: 'label'
},
// 树形列表
treeData: {
type: Array,
default: () => []
},
// 单选0 多选1
isSingle: {
type: String,
default: '0'
}
},
setup(props, ctx) {
const selectRef = ref(null)
const treeListDept = ref(null)
const diaData = reactive({
propsDefault: {
label: props.labelVal
},
nodeKey: props.idVal,
label: [], // 展示名字
labelRealVal: [], // 全部数据-id、label
showIndex: true
})
onMounted(() => {
})
watch(()=> props.labelId, (val)=> {
console.log(props.labelId, val, 'ssssss')
nextTick(() => {
treeListDept.value.setCheckedKeys(val)
})
},
{
deep: true,
immediate: true
})
// 父级树监听选择值
let checkChangeTree = (data, data2) => {
if(props.isSingle == '1') {
// 多选
if(data2) {
diaData.label.push( data[`${props.labelVal}`] )
diaData.labelRealVal.push( {id: data[`${props.idVal}`], label: data[`${props.labelVal}`]} )
}
else {
let index = diaData.labelRealVal.findIndex((item) => {
return item.id == data[`${props.idVal}`]
})
if(diaData.showIndex) {
diaData.label.splice(index, 1)
diaData.labelRealVal.splice(index, 1)
}
diaData.showIndex = true
}
} else {
// 单选
if(data2) {
treeListDept.value.setCheckedKeys([ data[`${props.idVal}`] ])
diaData.label = [ data[`${props.labelVal}`] ]
diaData.labelRealVal = [{ id: data[`${props.idVal}`], label: data[`${props.labelVal}`] }]
} else {
diaData.labelRealVal.forEach((item) => {
if(item.id == data.id) {
diaData.label = []
diaData.labelRealVal = []
}
})
}
}
checkVal()
}
// 标签删除
let removeTag = (tag) => {
if(props.isSingle == '1') {
// 多选
diaData.labelRealVal.findIndex((item, index) => {
console.log(item)
if(item.label == tag) {
treeListDept.value.setChecked(item.id, false)
diaData.labelRealVal.splice(index, 1)
diaData.showIndex = false
}
return item.label == tag
})
} else {
// 单选
treeListDept.value.setCheckedKeys([])
}
}
// 将选中值,返回给父组件
const checkVal =()=> {
ctx.emit('selectTreeVal', diaData.labelRealVal)
}
const closeSelect=()=> {
selectRef.value.blur()
}
return {
...toRefs(diaData),
treeListDept,
checkChangeTree,
removeTag,
checkVal,
selectRef,
closeSelect
}
},
}
</script>
<style lang="scss" scoped>
.selectClose {
text-align: right;
padding: 15px 15px 0px 15px;
font-size: 16px;
i {
cursor: pointer;
}
}
</style>