124 lines
3.0 KiB
Vue
124 lines
3.0 KiB
Vue
<template>
|
|
<n-cascader label-field="name" value-field="areaCode" :options="optionsData" placeholder="请选择所属区域" remote ref="cascaderInstRef"
|
|
:on-load="loadData" clearable :disabled="disabled" v-model:value="selectedOptions" check-strategy="child" show-path
|
|
@update:value="handleUpdateValue"/>
|
|
</template>
|
|
<script setup lang="ts" name="china-area">
|
|
import { ref, onMounted, computed, watch } from 'vue'
|
|
import { getCityByList } from "@/api/system/user";
|
|
import type { CascaderOption } from 'naive-ui'
|
|
const emit = defineEmits(['update:modelValue', 'change']);
|
|
const optionsData = ref([]);
|
|
const tempData=ref([])
|
|
const cascaderInstRef = ref()
|
|
const props = defineProps({
|
|
// 当前的值
|
|
modelValue: [String,Array],
|
|
// 类型 (二级联动,三级联动)
|
|
type: {
|
|
type: Number,
|
|
default: 3,
|
|
},
|
|
// 是否禁用
|
|
disabled: {
|
|
type: Boolean,
|
|
default: () => false,
|
|
},
|
|
});
|
|
|
|
watch(
|
|
() => props,
|
|
async () => {
|
|
if(props && props.modelValue.length >0){
|
|
if(optionsData.value.length==0) {
|
|
const data = await getCityByList(0)
|
|
data.map(item => {
|
|
item.isLeaf = false
|
|
})
|
|
optionsData.value = data
|
|
}
|
|
setData(props.modelValue);
|
|
}
|
|
},
|
|
{
|
|
deep: true,
|
|
},
|
|
);
|
|
const getCityData = async (pid: any) => {
|
|
const data = await getCityByList(pid)
|
|
data.map(item => {
|
|
item.isLeaf = false
|
|
})
|
|
return data
|
|
}
|
|
const changeFlag = ref(false)
|
|
const selectedOptions = computed({
|
|
get: () => {
|
|
return props.modelValue[3];
|
|
},
|
|
set: (val) => {
|
|
emit('update:modelValue', tempData.value);
|
|
},
|
|
});
|
|
const setData = async (data) => {
|
|
if (changeFlag.value) return
|
|
let index1 = findListChild(optionsData.value, data[0])
|
|
let data1 = await getCityByList(data[0])
|
|
optionsData.value[index1].children = data1
|
|
|
|
|
|
let index2 = findListChild(data1, data[1])
|
|
let data2 = await getCityByList(data[1])
|
|
optionsData.value[index1].children[index2].children = data2
|
|
|
|
|
|
let index3 = findListChild(data2, data[2])
|
|
let data3 = await getCityByList(data[2])
|
|
optionsData.value[index1].children[index2].children[index3].children = data3
|
|
|
|
}
|
|
|
|
const findListChild = (list: any, value: any) => {
|
|
let child = null
|
|
let index = 0
|
|
for (let i = 0; i < list.length; i++) {
|
|
if (list[i].areaCode == value) {
|
|
child = list[i]
|
|
index = i
|
|
break;
|
|
}
|
|
}
|
|
return index
|
|
}
|
|
const loadData = async (option: CascaderOption) => {
|
|
tempData.value[option.level]=option.areaCode
|
|
return new Promise<void>(async (resolve) => {
|
|
const data = await getCityByList(option.areaCode)
|
|
data.map(item => {
|
|
item.isLeaf = item.level==3?true:false
|
|
})
|
|
option.children = data
|
|
resolve()
|
|
})
|
|
};
|
|
const handleUpdateValue =(val)=>{
|
|
if(val){
|
|
changeFlag.value = true
|
|
tempData.value[3] = val
|
|
}
|
|
}
|
|
|
|
onMounted(async () => {
|
|
const data = await getCityByList(0)
|
|
data.map(item => {
|
|
item.isLeaf = false
|
|
})
|
|
optionsData.value = data
|
|
});
|
|
</script>
|
|
<style lang="less">
|
|
.ant-cascader-menu {
|
|
background-color: #ffffff;
|
|
}
|
|
</style>
|