1.组件
<template>
<div class="selection">
<el-select placeholder="请选择" v-model="nameList" clearable @clear="handleClear" ref="selectUpResId" style="width: 100%">
<el-option hidden :key="1" :value="1"></el-option
><!--这个必不可少否则显示不出来下拉数据-->
<!-- check-strictly :父子是否联动,根据业务修改 -->
<el-tree
:data="options"
node-key="id"
:props="defaultProps"
:default-checked-keys="huixianarr"
@check="handleNodeClick"
show-checkbox
ref="treeRef"
:check-strictly="true"
>
</el-tree>
</el-select>
</div>
</template>
<script setup name="selects">
import { ref, reactive } from "vue";
//接受父组件传来的数据
const props = defineProps({
treeFilterData: {
type: Array,
default: () => [] //树形控件数据源
},
treeHxlist: {
type: Array,
default: () => [] //回显ID集合,根据业务修改
},
dfProps: {
type: Object,
default: () => {} //树形控件配置项,根据业务修改
}
});
const treeRef = ref();
let nameList = ref("");
let huixianarr = ref([]);
let idList = ref();
let options = ref([]);
let defaultProps = ref({});
defaultProps.value = props.dfProps;
let hxlist = ref([]);
let treeForm = ref();
let list = ref();
var propertyName = props.dfProps.label;
init();
function init() {
options.value = props.treeFilterData;
huixianarr.value = props.treeHxlist;
let hxlist = findPathsByIds(options.value, huixianarr.value);
nameList.value = hxlist.join(","); //显示内容
}
const emit = defineEmits(["checKedId"]);
function handleNodeClick(data, lst) {
let arr = [],
name = [];
lst.checkedNodes.forEach(item => {
//过滤拿到选中的id
arr.push(item.id);
});
lst.checkedNodes.forEach(item => {
//过滤拿到选中的name
name.push(item[propertyName]);
});
nameList.value = name.join(","); //显示内容
idList.value = arr; //后台传参需要的id
//传给父组件
emit("checKedId", idList.value);
}
function handleClear() {
hxlist.value = [];
idList.value = []; //id集合
nameList.value = ""; //input显示内容
huixianarr.value = []; //回显ID集合
treeRef.value.setCheckedKeys([]); //清空
}
function findPathsByIds(data, targetIds) {
const resultPaths = []; // 存储匹配的 title
// 辅助函数:递归查找单个 id 的 title
function findPathRecursive(items, targetId) {
for (const item of items) {
// 如果当前项的 id 匹配,添加其 title 到结果数组
if (item.id === targetId) {
resultPaths.push(item[propertyName]);
return; // 找到后直接返回
}
// 如果有 children,递归查找
if (item.children && item.children.length > 0) {
findPathRecursive(item.children, targetId);
}
}
}
// 遍历目标 id 数组,逐一查找
for (const id of targetIds) {
findPathRecursive(data, id);
}
return resultPaths;
}
</script>
<style scoped>
.selection {
width: 300px;
}
</style>
2.使用
<Selectoption :treeFilterData="treeFilterData" :treeHxlist="treeHxlist" :dfProps="dfProps" @checKedId="gettreelist" />
//回显
const treeFilterData = ref([1]);
//格式
let dfProps = ref({
children: "children",
label: "title"
});
//数据
const treeFilterData = ref([
{
"id": 1,
"path": "/home/index",
"name": "home",
"component": "/home/index",
"title": "首页",
"meta": {
"icon": "HomeFilled",
"title": "首页",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": true,
"isKeepAlive": true
}
},
{
"id": 6,
"path": "/system",
"name": "system",
"redirect": "/system/accountManage",
"title": "系统管理",
"meta": {
"icon": "Tools",
"title": "系统管理",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": true
},
"children": [
{
"id": 61,
"father": 6,
"path": "/system/accountManage",
"name": "accountManage",
"component": "/system/accountManage/index",
"title": "账号管理",
"meta": {
"icon": "Menu",
"title": "账号管理",
"isLink": "",
"isHide": false,
"isFull": false,
"isAffix": false,
"isKeepAlive": true
}
},
]
}
]);