一、缘由
在项目开发过程中,有一个需求是省市区地址选择的功能,一开始想的是直接使用静态地址资源库本地打包,但这种方式不方便维护,于是放弃。后来又想直接让后台返回全部地址数据,然后使用级联选择器进行选择,但发现数据传输量有点大且处理过程耗时,于是又摒弃了这种方法。最后还是决定采用异步的方式进行省市区地址选择,即先查询省份列表,然后根据选择的省份code查询城市列表,最后根据选择的城市列表获取区/县列表,最终根据应用场景不同,给出了两种实现方案。
其中后台总共需要提供4个接口,一个查询所有省份的接口,一个根据省份code查询其下所有城市的接口,一个根据城市code查询其下所有区/县的接口,以及一个根据地址code转换成省市区三个code值的接口。
// 本人项目中使用的四个接口
${this.API.province}/${countryCode}
// 根据国家code查询省份列表,中国固定为156,可以拓展
${this.API.city }/${provinceCode}
// 根据省份code查询城市列表
${this.API.area}/${cityCode}
// 根据城市code查询区/县列表
${this.API.addressCode}/${addressCode}
// 地址code转换为省市区code
二、基于el-cascader 级联选择器的单选择框实现方案
<template>
<el-row>
<el-cascader
size="small"
:options="city.options"
:props="props"
v-model="cityValue"
@active-item-change="handleItemChange"
@change="cityChange">
</el-cascader>
</el-row>
</template>
<script>
export default {
name: 'addressSelector',
props: {
areaCode: null
},
model: {
prop: 'areaCode',
event: 'cityChange'
},
data () {
return {
// 所在省市
city: {
obj: {
},
options: []
},
props: {
// 级联选择器的属性配置
value: 'value',
children: 'cities',
checkStrictly: true
},
cityValue: [], // 城市代码
}
},
computed: {
},
created () {
this._initData()
},
mounted () {
},
methods: {
_initData () {
this.$http({
method: 'get',
url: this.API.province + '/156' // 中国
}).then(res => {
this.city.options = res.data.body.map(item => {
// 所在省市
return {
value: item.provinceCode,
label: item.provinceName,
cities: []
}
})
})
},
getCodeByAreaCode (code) {
if (code == undefined) return false
this.$http({
method: 'get',
url: this.API.addressCode + '/' + code
})
.then(res => {
if (res.data.code === this.API.SUCCESS) {
let provinceCode = res.data.body.provinceCode
let cityCode = res.data.body.cityCode
let areaCode = res.data.body.areaCode
this.cityValue = [provinceCode, cityCode, areaCode]
this.handleItemChange([provinceCode, cityCode])
}
})
.finally(res => {
})
},
handleItemChange (value)