<script lang="ts" setup name="AddressSelect"> import countries from './country-code.json' import type { IAddress } from './address-interface' import { getAreaByPid } from '@/api/system/area' const props = defineProps({ /** * 数据列表: ['国家','省','市','区','详细地址'] */ data: { type: Array, default: () => [], }, /** * 是否可编辑 */ disabled: { type: Boolean, default: false, }, /** * 是否是详情展示 */ detail: { type: Boolean, default: false, }, }) const emit = defineEmits(['onChange']) // 下拉区域对象 interface IArea { id: string areaName: string } const countryList = ref(countries) const provinceList = ref<IArea[]>([]) // 省列表 const cityList = ref<IArea[]>([]) // 市列表 const areaList = ref<IArea[]>([]) // 区列表 // 地址对象 const addressObj: IAddress = reactive({ country: '', countryName: '', province: '', provinceName: '', city: '', cityName: '', area: '', areaName: '', address: '', }) function countryChange(countryCode: string, clear = true) { if (clear) { addressObj.province = '' addressObj.provinceName = '' addressObj.city = '' addressObj.cityName = '' addressObj.area = '' addressObj.areaName = '' } if (countryCode === 'CN') { getAreaByPid('0').then((res) => { provinceList.value = res.data }) } } // 省份变化 function provinceChange(provinceId: string, clear = true) { if (clear) { addressObj.city = '' addressObj.cityName = '' addressObj.area = '' addressObj.areaName = '' } getAreaByPid(provinceId).then((res) => { cityList.value = res.data }) // emit('onChange', addressObj) } // 城市变化 function cityChange(cityId: string, clear = true) { if (clear) { addressObj.area = '' addressObj.areaName = '' } getAreaByPid(cityId).then((res) => { areaList.value = res.data }) // emit('onChange', addressObj) } // 区域变化 function areaChange(areaId: string) { } // 监听参数变化 watch(() => props.data, (val) => { if (Array.isArray(val) && val.length == 5) { if (!props.detail) { addressObj.country = val[0] addressObj.province = val[1] addressObj.city = val[2] addressObj.area = val[3] addressObj.address = val[4] if (addressObj.country) { countryChange(addressObj.country, false) } if (addressObj.province) { provinceChange(addressObj.province, false) } if (addressObj.city) { cityChange(addressObj.city, false) } } else { // 详情,只给输入框复制 addressObj.countryName = val[0] addressObj.provinceName = val[1] addressObj.cityName = val[2] addressObj.areaName = val[3] addressObj.address = val[4] } } }) watch( () => addressObj, (val) => { // 如果无中文的,查找中文 if (addressObj.countryName == '') { addressObj.countryName = countryList.value.find(item => item.code == addressObj.country)?.CNName || '' } if (addressObj.provinceName == '') { addressObj.provinceName = provinceList.value.find(item => item.id == addressObj.province)?.areaName || '' } if (addressObj.cityName == '') { addressObj.cityName = cityList.value.find(item => item.id == addressObj.city)?.areaName || '' } if (addressObj.areaName == '') { addressObj.areaName = areaList.value.find(item => item.id == addressObj.area)?.areaName || '' } emit('onChange', addressObj) }, { immediate: false, deep: true }) </script> <template> <div> <!-- 国家 --> <el-select v-if="!detail" v-model="addressObj.country" class="address-select" placeholder="国家" @change="countryChange" > <el-option v-for="country of countryList" :key="country.code" :label="country.CNName" :value="country.code" /> </el-select> <el-input v-else v-model="addressObj.countryName" placeholder="" class="address-select" :class="{ 'detail-input': detail }" :disabled="detail" /> <!-- 省 --> <el-select v-if="!detail && (addressObj.country === '' || addressObj.country === 'CN')" v-model="addressObj.province" placeholder="省" :disabled="detail" class="address-select" @change="provinceChange" > <el-option v-for="province in provinceList" :key="province.id" :label="province.areaName" :value="province.id" /> </el-select> <el-input v-else-if="detail && addressObj.countryName === '中国'" v-model="addressObj.provinceName" placeholder="" class="address-select" :class="{ 'detail-input': detail }" :disabled="detail" /> <!-- 市 --> <el-select v-if="!detail && (addressObj.country === '' || addressObj.country === 'CN')" v-model="addressObj.city" placeholder="市" :disabled="detail" class="address-select" @change="cityChange" > <el-option v-for="city in cityList" :key="city.id" :label="city.areaName" :value="city.id" /> </el-select> <el-input v-else-if="detail && addressObj.countryName === '中国'" v-model="addressObj.cityName" placeholder="" class="address-select" :class="{ 'detail-input': detail }" :disabled="detail" /> <!-- 区 --> <el-select v-if="!detail && (addressObj.country === '' || addressObj.country === 'CN')" v-model="addressObj.area" placeholder="区/县" class="address-select" :disabled="detail" @change="areaChange" > <el-option v-for="area in areaList" :key="area.id" :label="area.areaName" :value="area.id" /> </el-select> <el-input v-else-if="detail && addressObj.countryName === '中国'" v-model="addressObj.areaName" placeholder="" class="address-select" :class="{ 'detail-input': detail }" :disabled="detail" /> <!-- 详细地址 --> <el-input v-model="addressObj.address" :placeholder="detail ? '' : '详细地址'" :disabled="detail" class="address-input" :class="{ 'detail-input': detail }" /> </div> </template> <style lang="scss" scoped> .address-select { width: 160px; margin-right: 5px; } .address-input { width: 280px; } </style>