TreeSelect 树形选择
含有 下拉菜单的树形选择器,结合了 e1-tree 和 e1-select 两个组件的功能
el-tree-select

<template>
<div class="main">
<div class="header">
<el-form :model="form" label-width="auto">
<!-- 区域选择 -->
<el-form-item label="区域" style="width: 200px; float: left">
<el-tree-select
v-model="form.areaIdList"
:data="optionOrgs"
:props="defaultProps"
clearable
multiple
show-checkbox
check-strictly
node-key="id"
placeholder="请选择区域"
style="width: 220px"
@change="handleAreaChange(form.areaIdList)"
collapse-tags
/>
</el-form-item>
</el-form>
</div>
</div>
</template>
<script lang="ts">
import { ref, reactive, toRefs, onMounted } from "vue";
import { useRouter, useRoute } from "vue-router";
export default {
name: "",
setup() {
let router = useRouter(),
route = useRoute();
const data: any = reactive({
form: {
areaIdList: [],
},
optionOrgs: [],
});
const defaultProps = {
label: "name",
children: "children",
isLeaf: (data: any) => {
return !data.children || data.children.length === 0;
},
};
const loading = ref(false);
const processAreaData = (areas: any) => {
return areas.map((area: { id: any; name: any; parentId: any; areaVos: any; }) => ({
id: area.id,
name: area.name,
parentId: area.parentId,
children: area.areaVos ? processAreaData(area.areaVos) : []
}));
};
const getAllAreas = async () => {
try {
const res={
"code": 1,
"message": null,
"success": true,
"data": [
{
"id": 358,
"areaCode": "1865",
"name": "常州市",
"areaGrade": 1,
"parentId": 0,
"areaMap": "",
"areaPos": "",
"isvalid": null,
"areaVos": [
{
"id": 361,
"areaCode": "7863",
"name": "万达广场中心店",
"areaGrade": 0,
"parentId": 358,
"areaMap": "",
"areaPos": "",
"isvalid": null,
"areaVos": []
},
{
"id": 362,
"areaCode": "7862",
"name": "东城营业厅",
"areaGrade": 0,
"parentId": 358,
"areaMap": "",
"areaPos": "",
"isvalid": null,
"areaVos": []
}
]
}
]
}
data.optionOrgs = processAreaData(res.data);
console.log(data.optionOrgs,'opop');
} catch (error) {
console.error("获取区域数据失败:", error);
}
};
const handleAreaChange = async (selectedAreaIds: number[]) => {
console.log(selectedAreaIds,'selectedAreaIds');
}
onMounted(async () => {
try {
await getAllAreas();
await handleAreaChange([]);
} catch (error) {
console.error("初始化失败:", error);
}
});
const refData = toRefs(data);
return {
...refData,
defaultProps,
handleAreaChange,
loading,
};
},
};
</script>
动态显示子节点

勾选父节点懒加载对应展示子节点
初始化展示父节点 点击父节点的id作为子节点的入参加载子节点的数据
<el-tree-select
v-model="form.areaIdList"
:data="optionOrgs"
:props="defaultProps"
:load="loadNode"
lazy
clearable
multiple
check-strictly
node-key="id"
placeholder="请选择区域"
style="width: 220px"
@change="handleAreaChange(form.areaIdList)"
collapse-tags
/>
<script lang="ts">
import { ref, reactive, toRefs, onMounted } from "vue";
export default {
setup() {
const data: any = reactive({
form: {
areaIdList: [],
},
optionOrgs: [],
})
const defaultProps = {
label: "name",
children: "children",
isLeaf: (data: any) => {
return data.child === 0;
},
};
const loadNode = async (node: any, resolve: Function) => {
console.log(node,'opop');
try {
let res;
if (node.level === 0) {
res = await getOrg({ pid: 0 });
} else {
res = await getOrgSon({ areaId: node.data.id });
}
const formattedNodes = res.map((item) => ({
id: item.id,
name: item.name,
parentId: item.parentId,
child: item.child,
}));
resolve(formattedNodes);
} catch (error) {
console.error("加载节点失败:", error);
resolve([]);
}
};
const refData = toRefs(data);
return {
...refData,
loadNode,
}
}
}
</script>
动态显示勾选数据
2个选择器一个是TreeSelect(el-tree-select)
另一个是el-select
el-select的数据是基于el-tree-select的勾选动态加载显示的
勾选多个时以逗号分隔 在区域选择对应值
设备随着区域选择的值当成入参请求接口返回动态展示数据
区域的值与设备展示数据是同步的
<!-- 区域选择 -->
<el-form-item label="区域">
<el-tree-select
v-model="form.areaIdList"
:data="optionOrgs"
:props="defaultProps"
clearable
multiple
show-checkbox
check-strictly
node-key="id"
placeholder="请选择区域"
style="width: 220px"
@change="handleAreaChange(form.areaIdList)"
collapse-tags
/>
</el-form-item>
<!-- 设备选择 -->
<el-form-item label="设备">
<el-select
v-model="form.deviceIdList"
multiple
clearable
filterable
placeholder="请选择设备"
style="width: 220px"
collapse-tags
:loading="loading"
>
<el-option
v-for="item in deviceOptions"
:key="item.id"
:label="item.name"
:value="item.id"
/>
</el-select>
</el-form-item>
<el-button
type="primary"
@click="btnInquire"
plain
small
style="margin: 0 0 0 10px"
>查询</el-button
>
<script lang="ts">
import { ref, reactive, toRefs, onMounted } from "vue";
export default {
setup() {
const data: any = reactive({
form: {
areaIdList: [],
deviceIdList: [],
},
optionOrgs: [],
deviceOptions: [],
allDevices: [],
})
const defaultProps = {
label: "name",
children: "children",
isLeaf: (data: any) => {
return !data.children || data.children.length === 0;
},
};
const loading = ref(false);
const processAreaData = (areas: any[]) => {
return areas.map(area => ({
id: area.id,
name: area.name,
parentId: area.parentId,
children: area.areaVos ? processAreaData(area.areaVos) : []
}));
};
const getAllAreas = async () => {
const res = await getOrg({ pid: 0 });
data.optionOrgs = processAreaData(res);
console.log("区域数据加载成功:", data.optionOrgs.length);
};
const handleAreaChange = async (selectedAreaIds: number[]) => {
data.form.deviceIdList = [];
data.deviceOptions = [];
if (selectedAreaIds.length === 0) {
const res = await getOrgSon({ areaId: 0 });
data.deviceOptions = res.map(device => ({
id: device.id,
name: device.name
}));
return;
}
const allDevices = [];
for (const areaId of selectedAreaIds) {
try {
const res = await getOrgSon({ areaId });
allDevices.push(...res);
} catch (error) {
console.error(`获取区域 ${areaId} 的设备失败`, error);
}
}
const uniqueDevices = [...new Map(allDevices.map(item => [item.id, item])).values()];
data.deviceOptions = uniqueDevices.map(device => ({
id: device.id,
name: device.name
}));
};
const tableLIst = async () => {
const params = {
keyword: data.form.name,
limit: data.tableList.limit,
offset: (data.tableList.offset - 1) * data.tableList.limit,
order: data.tableList.order,
sort: data.tableList.sort,
endTime: data.tableList.endTime,
startTime: data.tableList.startTime,
};
if (data.form.deviceIdList.length > 0) {
params['deviceIdList'] = data.form.deviceIdList.join(',');
} else {
if (data.deviceOptions.length > 0) {
const allDeviceIds = data.deviceOptions.map(device => device.id);
params['deviceIdList'] = allDeviceIds.join(',');
}
}
try {
const data1 = await Offlinelist(params);
data.tableData = data1;
} catch (error) {
console.error("获取表格数据失败:", error);
}
};
onMounted(async () => {
await getAllAreas();
await handleAreaChange([]);
await tableLIst();
});
const refData = toRefs(data);
return {
...refData,
defaultProps,
tableLIst,
handleAreaChange,
loading,
}
}
}
</script>