大概思路:
- 准备一个接口可以通过父Id,查询到下一级省市区街道的信息;如下方的getRegionListOne
- 确定后端的数据结构,需要在created里边处理数据回显逻辑
- el-cascader接收的数据格式是[‘’,‘’,‘’];后端的数据格式多为[{provinceId: ‘’, regionId: ‘’, cityId: ‘’}]
- 可以通过设置comType,来确定是省市区还是省市区街道,组件内完成逻辑处理。
直接上代码
<template><div class="areaLazy"><el-cascaderv-model="currentChoose"v-bind="_options":options="addressList":disabled="_options.disabled"@change="handleChange"/></div>
</template><script>
export default {name: "addresscascaderlazy",
};
</script><script setup>
import { ref, computed, watch } from "vue";
import API from "@/api";const emits = defineEmits(["update:modelValue"
]);const props = defineProps({disabled: {//禁用type: Boolean,required: false,default: false,},options: {type: Object,default: () => {},},modelValue: {type: [Array, Object],default: () => ([]),},
});
let id = 0;
// 设置option默认值,如果传入自定义的配置则合并option配置项
const _options = computed(() => {const option = {name: "multipartFiles",comType: "provinceCityCountryRegion",props: {lazy: true,lazyLoad(node, resolve) {const { level, value } = node; // 获取当前node对象中的level, value属性getArea(level, value, resolve)},}};option.disabled = props.disabled;return Object.assign(option, props.options);
});
const levelTag = {"provinceCityCountryRegion": 3,"provinceCityCountry": 2,"provinceCity": 1,
}
const currentChoose = ref([]);
const addressList = ref([]);
const addressOrigin = ref({}); // 省市区数据const handleChange = (val) => {console.log('handleChange', val)if (!val.length) {emits('update:modelValue', val)return}if (_options.value?.props?.multiple) {const arr = []val.forEach(item => {const obj = {}obj.provinceId = item[0]obj.provinceName = addressOrigin.value[0][item[0]]obj.cityId = item[1]obj.cityName = addressOrigin.value[1][item[1]]obj.regionId = item[2]obj.regionName = addressOrigin.value[2][item[2]]obj.streetId = val[3]obj.streetName = addressOrigin.value[3][val[3]]arr.push(obj)})emits('update:modelValue', arr)} else {const obj = {}obj.provinceId = val[0]obj.provinceName = addressOrigin.value[0][val[0]]obj.cityId = val[1]obj.cityName = addressOrigin.value[1][val[1]]obj.regionId = val[2]obj.regionName = addressOrigin.value[2][val[2]]obj.streetId = val[3]obj.streetName = addressOrigin.value[3][val[3]]emits('update:modelValue', obj)}
}const getArea = (level, value, resolve) => {API.getRegionListOne({parentId: value}).then(async (res) => {addressOrigin.value[level] = {}const nodes = res.result.map(item => {addressOrigin.value[level][item.id] = item.namereturn { value: String(item.id),label: item.name,leaf: level >= levelTag[_options.value?.comType],}})resolve(nodes)})
}const created = () => {if (!props.modelValue) {return []}if (props.modelValue instanceof Array) {currentChoose.value = props.modelValue.map(item => {if (_options.value.comType === "provinceCityCountryRegion") {return [ item.provinceId, item.cityId, item.regionId, item.streetId ]}if (_options.value.comType === "provinceCityCountry") {return [ item.provinceId, item.cityId, item.regionId ]}return [ item.provinceId, item.cityId ]})} else {if (_options.value.comType === "provinceCityCountryRegion") {currentChoose.value = [props.modelValue.provinceId, props.modelValue.cityId, props.modelValue.regionId, props.modelValue.streetId]return}if (_options.value.comType === "provinceCityCountry") {currentChoose.value = [props.modelValue.provinceId, props.modelValue.cityId, props.modelValue.regionId, props.modelValue.streetId]return}currentChoose.value = [props.modelValue.provinceId, props.modelValue.cityId]}
}// 省市区
// getaddressList();
watch(()=>props.modelValue, (val) => {created();
})</script><style lang="less">
.areaLazy {.el-input__inner {min-width: 350px;}
}
</style>
再附一个非懒加载形式的
<template><div class="areaUnit"><el-cascaderv-model="currentChoose"v-bind="_options":options="addressList":disabled="_options.disabled"@change="handleChange"/></div>
</template><script>
export default {name: "addresscascader",
};
</script><script setup>
import { ref, computed, watch } from "vue";
import API from "@/api";const emits = defineEmits(["update:modelValue"
]);const props = defineProps({disabled: {//禁用type: Boolean,required: false,default: false,},options: {type: Object,default: () => {},},modelValue: {type: [Array, Object],default: () => ([]),},
});// 设置option默认值,如果传入自定义的配置则合并option配置项
const _options = computed(() => {const option = {name: "multipartFiles",comType: "provinceCityCountry",};option.disabled = props.disabled;return Object.assign(option, props.options);
});const currentChoose = ref([]);
const addressList = ref([]);
const addressOrigin = ref({});
// 处理省市区数据结构
const handleBase = (list, childrenList, stringBan) => {return new Promise((resolve) => {const address = []if (childrenList) {for (const key in list) {const children = childrenList.filter(i => String(i.value).substring(0, stringBan) === String(key).substring(0, stringBan));address.push({value: key,label: list[key],children})}} else {for (const key in list) {address.push({value: key,label: list[key]})}}resolve(address)})
}// 获取省市区
const getaddressList = () => {API.getRegionList().then(async (res) => {const { province_list, city_list, county_list } = res.result;addressOrigin.value = { province_list, city_list, county_list }if (_options.value.comType === "provinceCityCountry") {const countyAddress = await handleBase(county_list)const cityAddress = await handleBase(city_list, countyAddress, 4)addressList.value = await handleBase(province_list, cityAddress, 2)}if (_options.value.comType === "provinceCity") {const cityAddress = await handleBase(city_list)addressList.value = await handleBase(province_list, cityAddress, 2)}})
}
const handleChange = (val) => {if (!val.length) {emits('update:modelValue', val)return}if (_options.value?.props?.multiple) {const arr = []val.forEach(item => {const obj = {}obj.provinceId = item[0]obj.provinceName = addressOrigin.value.province_list[item[0]]obj.cityId = item[1]obj.cityName = addressOrigin.value.city_list[item[1]]obj.regionId = item[2]obj.regionName = addressOrigin.value.county_list[item[2]]arr.push(obj)})emits('update:modelValue', arr)} else {const obj = {}obj.provinceId = val[0]obj.provinceName = addressOrigin.value.province_list[val[0]]obj.cityId = val[1]obj.cityName = addressOrigin.value.city_list[val[1]]obj.regionId = val[2]obj.regionName = addressOrigin.value.county_list[val[2]]emits('update:modelValue', obj)}
}const created = () => {if (!props.modelValue) {return []}if (props.modelValue instanceof Array) {currentChoose.value = props.modelValue.map(item => {if (_options.value.comType === "provinceCityCountry") {return [ item.provinceId, item.cityId, item.regionId ]}return [ item.provinceId, item.cityId ]})} else {if (_options.value.comType === "provinceCityCountry") {currentChoose.value = [props.modelValue.provinceId, props.modelValue.cityId, props.modelValue.regionId]} else {currentChoose.value = [props.modelValue.provinceId, props.modelValue.cityId]}}
}// 省市区
getaddressList();
watch(()=>props.modelValue, (val) => {console.log('modelValue', val)created();
})
</script>