中国省市区地区选择组件(ElementPlus + Vue3 + TS )
安装
| npm install element-china-area-data -S |
复制
介绍
1.引用
| import { provinceAndCityData, regionData, provinceAndCityDataPlus, regionDataPlus, CodeToText, TextToCode } from 'element-china-area-dat |
| |
复制
2.用法
provinceAndCityData:省市数据(不带“全部”选项)
regionData:省市区数据(不带“全部”选项)
provinceAndCityDataPlus:省市区数据(带“全部”选项)
regionDataPlus:省市区数据(带“全部”选项)
CodeToText:例如:CodeToText[‘110000’]输出北京市
TextToCode:例如:TextToCode[‘北京市’].code输出110000
代码
| <template> |
| <div class="areabox"> |
| <el-select v-model="address.province" placeholder="请选择省" |
| :style="{ width: `${prop.width}px`, marginRight: `${prop.gap}px` }" @change="handleProvinceSelect"> |
| <el-option v-for="item in regionData" :label="item.label" :value="item.value" /> |
| </el-select> |
| <el-select v-model="address.city" placeholder="请选择市" :disabled="!address.province || cityList.length == 0" |
| :style="{ width: `${prop.width}px`, marginRight: `${prop.gap}px` }" @change="handleCitySelect"> |
| <el-option v-for="item in cityList" :label="item.label" :value="item.value" /> |
| </el-select> |
| <el-select v-model="address.area" placeholder="请选择区" :style="{ width: `${prop.width}px` }" |
| :disabled="!address.province || !address.city || areaList.length == 0" @change="handleAreaSelect"> |
| <el-option v-for="item in areaList" :label="item.label" :value="item.value" /> |
| </el-select> |
| </div> |
| </template> |
| <script lang="ts" setup> |
| import { reactive, computed, ComputedRef } from 'vue' |
| import { regionData, CodeToText } from 'element-china-area-data' |
| const prop = withDefaults( |
| defineProps<{ |
| gap: string | number //选择框中间间隙 |
| width: string | number //选择框宽度 |
| }>(), |
| { |
| gap: '8', |
| width: '210' |
| } |
| ) |
| //抛出地址 |
| const emit = defineEmits<{ |
| (e: 'getAddress', data: { |
| code: string[] //区域码 |
| name: string[] //汉字 |
| isComplete: boolean //是否选择完整,方便校验 |
| }): void |
| }>() |
| let address = reactive<{ |
| province: string |
| city: string |
| area: string |
| }>({ |
| province: '', |
| city: '', |
| area: '' |
| }) |
| interface AreaList { |
| value: string |
| label: string |
| children?: AreaList[] |
| } |
| //切换省份函数 |
| const handleProvinceSelect = () => { |
| address.city = '' |
| address.area = '' |
| emit('getAddress', { |
| code: [address.province], //区域码 |
| name: [CodeToText[address.province]], //汉字 |
| isComplete: false |
| }) |
| } |
| //切换城市函数 |
| const handleCitySelect = () => { |
| address.area = '' |
| emit('getAddress', { |
| code: [address.province, address.city], //区域码 |
| name: [CodeToText[address.province], CodeToText[address.city]], //汉字 |
| isComplete: areaList.value.length == 0 ? true : false |
| }) |
| } |
| //切换地区函数 |
| const handleAreaSelect = () => { |
| emit('getAddress', { |
| code: [address.province, address.city, address.area], //区域码 |
| name: [CodeToText[address.province], CodeToText[address.city], CodeToText[address.area]], //汉字 |
| isComplete: true |
| }) |
| } |
| //二级城市列表 |
| const cityList: ComputedRef<AreaList[]> = computed((): AreaList[] => { |
| if (!address.province) { return [] } |
| let temp = regionData.find((item: any) => { |
| return item.value == address.province |
| }) |
| return temp.children ? temp.children : [] |
| }) |
| //三级地区列表 |
| const areaList: ComputedRef<AreaList[]> = computed((): AreaList[] => { |
| if (!address.province || !address.city) { return [] } |
| if (cityList.value.length == 0) { |
| return [] |
| } else { |
| let temp = cityList.value.find((item: any) => { |
| return item.value == address.city |
| }) |
| if (temp) { |
| return temp.children ? temp.children : [] |
| } else { |
| return [] |
| } |
| } |
| }) |
| </script> |
| <style scoped> |
| .areabox { |
| display: flex; |
| align-items: center; |
| } |
| </style> |
复制
效果图
1.项目需要这种三个下拉选择框

2.选择地址





表单校验
| |
| import type { FormRules } from 'element-plus' |
| export const FJRrules = reactive<FormRules>({ |
| adress:[ |
| {required: true,validator: addressValidator , trigger: 'change' } |
| ], |
| }) |
| const addressValidator = (rule: any, value: any, callback: any) => { |
| if (!value) { |
| return callback(new Error('请选择省/市/区')) |
| } |
| setTimeout(() => { |
| if (!value.isComplete) { |
| callback(new Error('请完善地址')) |
| } else { |
| callback() |
| } |
| }, 100) |
| } |
复制
| <template> |
| <el-form ref="FJRformRef" inline :model="FJRForm" label-width="120px" :rules="FJRrules"> |
| <el-form-item prop="adress" label="省/市/区" required> |
| <area-selected @get-address="handleGetAdress"></area-selected> |
| </el-form-item> |
| </el-form> |
| </template> |
| <script lang="ts" setup> |
| import { FJRrules } from '这里是校验ts文件的地址'; |
| const FJRForm = reactive({ |
| adress:null, |
| }) |
| |
| const handleGetAdress = (data:any)=>{ |
| FJRForm.adress = data |
| } |
| </script> |
复制