Vue 3 + TypeScript 实现的省市区级联选择组件
<template>
<div class="cascader">
<select v-model="selectedProvince" @change="handleProvinceChange">
<option value="">请选择省份</option>
<option v-for="province in provinces" :key="province.code" :value="province.code">
{{ province.name }}
</option>
</select>
<select v-model="selectedCity" @change="handleCityChange" :disabled="!selectedProvince">
<option value="">请选择城市</option>
<option v-for="city in cities" :key="city.code" :value="city.code">
{{ city.name }}
</option>
</select>
<select v-model="selectedDistrict" :disabled="!selectedCity">
<option value="">请选择区县</option>
<option v-for="district in districts" :key="district.code" :value="district.code">
{{ district.name }}
</option>
</select>
</div>
</template>
<script lang="ts" setup>
import { ref, computed, watch } from 'vue';
interface Area {
code: string;
name: string;
children?: Area[];
}
// 模拟数据,实际应用中应该从API获取
const areaData: Area[] = [
{
code: '110000',
name: '北京市',
children: [
{
code: '110100',
name: '北京市',
children: [
{ code: '110101', name: '东城区' },
{ code: '110102', name: '西城区' },
// ... 其他区
],
},
],
},
// ... 其他省份
];
const selectedProvince = ref('');
const selectedCity = ref('');
const selectedDistrict = ref('');
const provinces = computed(() => areaData);
const cities = computed(() => {
const province = areaData.find(p => p.code === selectedProvince.value);
return province?.children || [];
});
const districts = computed(() => {
const province = areaData.find(p => p.code === selectedProvince.value);
const city = province?.children?.find(c => c.code === selectedCity.value);
return city?.children || [];
});
const handleProvinceChange = () => {
selectedCity.value = '';
selectedDistrict.value = '';
};
const handleCityChange = () => {
selectedDistrict.value = '';
};
watch([selectedProvince, selectedCity, selectedDistrict], (newValues) => {
const [province, city, district] = newValues;
console.log('Selected:', { province, city, district });
// 这里可以触发一个事件,将选中的值传递给父组件
});
</script>
<style scoped>
.cascader {
display: flex;
gap: 10px;
}
select {
padding: 5px;
font-size: 16px;
}
</style>
这个组件实现了以下功能:
- 使用
ref
来管理选中的省、市、区的值。 - 使用
computed
属性来动态计算可选的城市和区县列表。 - 当选择省份时,会重置市和区的选择。
- 当选择城市时,会重置区的选择。
- 使用
watch
来监听选择的变化,并在控制台输出选中的值。
要使用这个组件,可以在父组件中这样引入:
<template>
<div>
<h1>地址选择</h1>
<AreaCascader />
</div>
</template>
<script lang="ts" setup>
import AreaCascader from './AreaCascader.vue';
</script>
关注微信公众号温暖前端,不定期分享前端知识点和前端资料↓↓↓