基于elementui plus + vue3 + ts封装省市区乡镇通用下拉框组件

省市区数据下载地址

感谢[泥鸽鸽]同学的提醒,之前由于疏忽,没有贴上省市区数据的下载地址
省市区数据下载地址: 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的用法

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值