114 lines
3.0 KiB
Vue

<!-- AreaCascader.vue -->
<template>
<a-cascader v-model:value="modelValue" :options="options" :load-data="loadData" :placeholder="placeholder"
:style="style" :disabled="disabled" :show-search="showSearch" :allow-clear="allowClear"
:change-on-select="changeOnSelect" :field-names="fieldNames" @change="handleChange" />
</template>
<script setup>
import { ref, watch, onMounted,defineModel } from 'vue';
import apis from '@/apis'
import { useDicsStore } from '@/store'
const dicsStore = useDicsStore()
// 使用 defineModel 自动处理 v-model
const modelValue = defineModel();
// 接收 props
const props = defineProps({
placeholder: {
type: String,
default: '请选择省市区'
},
style: {
type: Object,
default: () => ({ width: '100%' })
},
disabled: {
type: Boolean,
default: false
},
showSearch: {
type: Boolean,
default: true
},
allowClear: {
type: Boolean,
default: true
},
changeOnSelect: {
type: Boolean,
default: false // 通常只在最后一级选择后触发
},
fieldNames: {
type: Object,
default: () => ({
label: 'label',
value: 'code',
// children: 'children'
})
}
});
// 定义 emit
const emit = defineEmits(['change']);
// 本地选项数据(初始为空,异步加载)
const options = ref([]);
watch(
() => dicsStore.provinceOptions,
(newVal) => {
if (newVal && newVal.length > 0) {
options.value = newVal
}
},
{ immediate: true } // 🔥 关键:组件初始化时也会执行一次
)
// onMounted(async () => {
// // 使用 store 中的省份数据
// options.value = await dicsStore.provinceOptions
// });
// 异步加载子节点(市、区)
const loadData = async (selectedOptions) => {
console.log('加载子节点, 选中选项:', selectedOptions);
const targetOption = selectedOptions[selectedOptions.length - 1];
targetOption.loading = true;
try {
const response = await apis.common.getAreaList({ current:1,pageSize:100,parentId: targetOption.id });
targetOption.loading = false;
if (Array.isArray(response.data)) {
const children = response.data.map(item => ({
...item,
isLeaf: !item.hasChild // 区/县 级别设为叶子节点
}));
// 更新 children
targetOption.children = children;
} else {
targetOption.children = [];
}
// 触发视图更新
options.value = [...options.value];
} catch (error) {
console.error('加载子节点失败:', error);
targetOption.children = [];
targetOption.loading = false;
}
};
// 处理选择变化
const handleChange = (value, selectedOptions) => {
emit('change', value, selectedOptions.map(option => option.label));
};
</script>
<style scoped>
/* 可根据需要添加样式 */
</style>