封装组件库-省市区选择器
2023, Feb 22
实现省市区选择器
基于Element-plus框架的Select选择器,封装为省市区选择器。
初始配置
- 注册路由组件chooseArea,配置为Container组件的子路由组件
- 采用路由懒加载,箭头函数异步引入组件。
- 注册通用组件ChooseArea,为路由组件的子组件,以便组件间通信。
省市区控制逻辑
//利用Select选择器的disable属性进行控制,逻辑||表示前面为true返回前面,false返回后面
<el-select placeholder="请选择省份" v-model="province">
<el-option></el-option>
</el-select>
<el-select clearable :disabled="!province" placeholder="请选择城市" v-model="city" style="margin: 0 10px">
<el-option></el-option>
</el-select>
<el-select clearable :disabled="!province || !city" placeholder="请选择区域" v-model="area">
<el-option></el-option>
</el-select>
//省份
let province = ref<string>('')
//城市
let city = ref<string>('')
//地区
let area = ref<string>('')
省市区数据获取并展示
在github上搜索省市区数据,格式为json
import allAreas from '../lib/pca-code.json'
let areas = ref(allAreas)
//areas示例,code类型为string
areas:{
code:11,
name:'北京',
children:[]
}
- 省份数据获取
<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>
- 所在省份的城市数据获取
定义接口类型,?定义在变量后面表示可选操作
export interface AreaItem { name: string, code: string, children?: AreaItem[] }
获取数据:
let selectCity = ref<AreaItem[]>([]) watch(()=>province.value,val=>{ if(val){ //!表示可将空值赋给变量并通过编译 let cities = areas.value.find(item=>item.code === province.value)?.children! selectCity.value = cities } //监听province.value变化,则清空市和区 city.value='' area.value = '' }) <el-select clearable :disabled="!province" placeholder="请选择城市" v-model="city" style="margin: 0 10px"> <el-option v-for="item in selectCity" :key="item.code" :value="item.code" :label="item.name"></el-option> </el-select>
- 所在城市的区域数据获取
let selectArea = ref<AreaItem[]>([]) watch(()=>city.value,val=>{ if(val){ let area = selectCity.value.find((item:{code:string}) =>item.code===city.value)?.children! selectArea.value = area } area.value = '' }) <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>
向父组件传值
- 传值类型
export interface Data { name:string, code: string }
- 与父组件通信
//分发事件给父组件
let emit = defineEmits(['change'])
//监听区域
watch(()=>area.value,val=>{
//if条件的作用是,防止未选择区域时向父组件传值
if(val){
let provinceData: Data = {
code: province.value,
//&&的作用是确保province.value有值
name: province.value && allAreas.find(item=>item.code === province.value)!.name,
}
let cityData: Data = {
code: city.value,
//必须要有city.value
name: city.value && selectCity.value.find(item=>item.code===city.value)!.name
}
let areaData: Data = {
code: area.value,
name: area.value && selectArea.value.find(item=>item.code === area.value)!.name
}
emit('change',{
province: provinceData,
city: cityData,
area: areaData
})
}
})
- 父组件
<my-choose-area @change="changeArea"></my-choose-area>
let changeArea = (val: any)=>{
console.log(val)
}