省市区数据下载地址
感谢[泥鸽鸽]同学的提醒,之前由于疏忽,没有贴上省市区数据的下载地址
省市区数据下载地址: https://github.com/modood/Administrative-divisions-of-China
效果图
当前一个下拉框没有被选中时,之后的下拉框为不可选状态
完整示意图
知识点
组件封装、父子组件传值、监听、事件
主要代码
<template>
<div>
<el-select clearable placeholder="请选择省份" v-model="province">
<el-option v-for="item in areas"
:key="item.code"
:value="item.code"
:label="item.name"
></el-option>
</el-select>
<el-select clearable :disabled="!province"
style="padding: 10px"
placeholder="请选择城市"
v-model="city">
<el-option
v-for="item in selectCity"
:key="item.code"
:value="item.code"
:label="item.name">
</el-option>
</el-select>
<el-select clearable
:disabled="!province || !city"
placeholder="请选择区域"
v-model="area">
<el-option v-for="item in selectArea"
:key="item.code"
:value="item.code"
:label="item.name">
</el-option>
</el-select>
<el-select clearable
:disabled="!province || !city || !area"
placeholder="请选择乡镇"
style="padding: 10px"
v-model="town">
<el-option v-for="item in selectTown"
:key="item.code"
:value="item.code"
:label="item.name">
</el-option>
</el-select>
</div>
</template>
<script lang="ts" setup>
//城市数据
import allAreas from './lib/pcas-code.json'
import {ref, watch } from 'vue';
//定义城市数据类型
export interface AreaItem {
name: string,
code: string,
children?: AreaItem[]
}
export interface Data{
name: string,
code: string
}
//分发事件给父组件
let emits = defineEmits(['change'])
//下拉框省市区乡镇
let province = ref<string>('')
let city = ref<string>('')
let area = ref<string>('')
let town = ref<string>('')
//mock数据
let areas = ref(allAreas)
// console.log(allAreas)
//城市下拉框所有的值
let selectCity = ref<AreaItem[]>([])
//区域下拉框所有的值
let selectArea = ref<AreaItem[]>([])
//乡镇下拉框所有的值
let selectTown = ref<AreaItem[]>([])
//监视选择省份下拉框
watch(()=>province.value, val => {
if (val) {
let cities = areas.
value.
find(item => item.code===province.value)!.children
selectCity.value = cities
}
city.value = ''
area.value = ''
town.value = ''
})
//监视选择城市下拉框
watch(()=>city.value, val => {
if (val) {
let area = selectCity
.value
.find(item => item.code === city.value)!
.children!
selectArea.value = area
}
area.value = ''
town.value = ''
})
//获取城镇数据
watch(() => area.value, val => {
if (val) {
let town = selectArea
.value
.find(item => item.code === area.value)!
.children!
selectTown.value = town
}
town.value = ''
})
//监听选择区域
watch(() => area.value, val => {
if (val) {
let provinceData: Data = {
code: province.value,
name: allAreas.find(item=> item.code === province.value)!.name
}
let cityData: Data = {
code: city.value,
name: selectCity.value.find(item=> item.code === city.value)!.name
}
let areaData: Data = {
code: area.value,
name: selectArea.value.find(item=> item.code === val)!.name
}
let townData: Data = {
code: area.value,
name: selectArea.value.find(item=> item.code === area.value)!.name
}
emits('change',{
province: provinceData,
city: cityData,
area: areaData,
town: townData
})
}
})
</script>
总结
加深 vue3的印象,巩固之前忘掉的知识,包括props父子组件传参、emit事件机制、watch的用法