一. 先弄实际效果
二. 需求背景
省市县镇乡多级联动, 依据父级懒加载表明子级, 写一个通用组件
- 这一通用组件必须满足双重数据绑定, 直接使用v-model, 能表格校检
- 交互形式维持统一的下拉选择挑选实际效果
- 不但新增加能够, 改动也可以正常的回显
三. 解决策略
vue3 element-plus
- 界定子组件接受值, 和3D渲染值;应用特性监视, 随后公布事情, 进行双向绑定
- 应用el-select部件, 随后用empty扩展槽, 裹住 el-cascader-panel
- 监视值更改时进行外键约束查询接口, 依据值获得相对应的地域目标
四. 代码逻辑
<template>
<el-select
v-model="provinceId"
placeholder="挑选地域"
class="selectLazy"
clearable
@change="changeSelect"
:disabled="disabled"
ref="selectLazyRef"
>
<template #prefix>
<div class="areaName" v-if="areaName">{{areaName}}</div>
<div class="empty" v-else>挑选地域</div>
</template>
<template #empty>
<el-cascader-panel
:props="propsCascader"
v-model="cascaderValue"
@change="changeCascader"
ref="cascaderLazyRef"
/>
</template>
</el-select>
</template>
<script setup>
import { provinceQuery, provinceById } from "@/api/system/dict/data";
const { proxy } = getCurrentInstance();
const props = defineProps({
modelValue: [String, Object, Array],
disabled: {
type: Boolean,
default: false
}
});
const cascaderValue = ref([]);
const selectLazyRef = ref(null);
const areaName = ref("");
const provinceId = ref("");
const propsCascader = {
label: "name",
value: "id",
checkStrictly: true,
lazy: true,
lazyLoad: cascaderLazyLoad,
};
watch(
() => props.modelValue,
(val) => {
provinceId.value = val;
getProvinceById();
},
{ deep: true, immediate: true }
);
const emit = defineEmits();
// 懒加载插口
function cascaderLazyLoad(node, resolve) {
if (!node) {
return false;
}
const { level } = node;
const { id } = node.data;
//level意味着现阶段点一下挑选哪一项,,例如0意味着第一次进去载入数据信息,1就是选择省后实际操作
if (level == 0) {
provinceQuery({ pid: 0 })
.then((res) => {
res.data.forEach((item) => {
item.leaf = false;
});
resolve(res.data);
})
.catch((err) => {
resolve([]);
});
} else {
if (id) {
provinceQuery({ pid: id })
.then((res) => {
res.data.forEach((item) => {
item.leaf = level >= 3;
});
resolve(res.data);
})
.catch((err) => {
resolve([]);
});
} else {
resolve([]);
}
}
}
// 数据信息 外键约束 查看
function getProvinceById() {
if (provinceId.value) {
provinceById({ id: provinceId.value }).then((res) => {
areaName.value = res.data.fullPath;
});
}
}
// 挑选 数据信息更改
function changeSelect() {;
cascaderValue.value = [];
areaName.value = "";
emit("update:modelValue", null);
selectLazyRef.value.visible = false;
}
// 级联 数据信息更改
function changeCascader() {;
let emitProvinceId =
cascaderValue.value && Array.isArray(cascaderValue.value)
? cascaderValue.value[cascaderValue.value.length - 1]
: cascaderValue.value; // 所属区域
emit("update:modelValue", emitProvinceId);
selectLazyRef.value.visible = false;
}
</script>
最终
自然, 这类并不是最佳方案, 确能迅速高效的解决问题;