Element-UI 省市区(县)三级联动
由于公司移动端使用的是Vux的UI框架,该框架有x-address组件,其中包含了省市县的数据,通过Element-UI实现与其相同的省市区(县)三级联动。
Vux中x-address对全国省市区的数据进行了封装,引入不同版本的JSON文件展示不同的内容,这里我引入的是V4版本(最新版本)的JSON数据,JSON格式如下图:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczLcVmds92czlGZvwVP9EUTDZ0aRJkSwk0LcxGbpZ2LcBDM08CXlpXazRnbvZ2LcRlMMVDT2EWNvwFdu9mZvwVPj1mYshmMZ5WNXp1ak1mYox2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39jNwQDMwIDN0EzNxATM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
思路:在此我列举了省市县的数据,相关数据下载,很明显省市区有各自的特性
1. 省的value是0000结尾;
2. 市的value是00结尾;同时又parent字段对应相应的省;
3. 区(县)parent字段对应的相应的市
直接上干货,相应的代码如下展示
HTML
<template>
<div>
<el-select v-model="valueProvince"
placeholder="请选择省"
@change="changeProvince">
<el-option
v-for="item in provinceList"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-select v-model="valueCity"
placeholder="请选择市"
@change="changeCity">
<el-option
v-for="item in cityOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<el-select v-model="valueOrigin"
placeholder="请选择区"
@change="changeOrigin">
<el-option
v-for="item in originOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</div>
</template>
JS
import axios from 'axios'
export default {
name: 'HelloWorld',
data () {
return {
provinceList: [], // 省列表
cityList: [], // 市列表
originList: [], // 区列表
valueProvince: '', // 所选的省
valueCity: '', // 所选的市
valueOrigin: '', // 所选的区
cityOptions: [], // 市下拉框数据
originOptions: [] // 区下拉框数据
}
},
methods: {
// 选择省
changeProvince(val) {
this.provinceList.forEach((province, index) => {
if (val.toString() === this.provinceList[index].value) {
this.cityOptions = this.provinceList[index].children
this.valueCity = this.provinceList[index].children[0].value
this.originOptions = this.provinceList[index].children[0].children
this.valueOrigin = this.provinceList[index].children[0].children[0].value
}
})
},
// 选择市
changeCity(val) {
this.cityList.forEach((city, index) => {
if (val.toString() === this.cityList[index].value) {
this.originOptions = this.cityList[index].children
this.valueOrigin = this.cityList[index].children[0].value
}
})
},
// 选择区
changeOrigin(val) {
this.valueOrigin = val
},
_getJsonData() {
axios.get('../../static/china_address_v4.json').then((res) => {
this.provinceList = []
this.cityList = []
this.originList = []
res.data.forEach((item) => {
if (item.value.match(/0000$/)) {
this.provinceList.push({
value: item.value,
label: item.name,
children: []
})
} else if (item.value.match(/00$/)) {
this.cityList.push({
value: item.value,
label: item.name,
children: []
})
} else {
this.originList.push({
value: item.value,
label: item.name
})
}
})
for (let index in this.provinceList) {
for (let index1 in this.cityList) {
if (this.provinceList[index].value.slice(0, 2) === this.cityList[index1].value.slice(0, 2)) {
this.provinceList[index].children.push(this.cityList[index1])
}
}
}
for(let item1 in this.cityList) {
for(let item2 in this.originList) {
if (this.originList[item2].value.slice(0, 4) === this.cityList[item1].value.slice(0, 4)) {
this.cityList[item1].children.push(this.originList[item2])
}
}
}
})
}
},
created() {
this._getJsonData()
}
}
这里我使用axios读取json文件,基于我之前的思路,遍历数据并正则匹配相应的数据(4个0对应省,2个0对应市,其他为区),添加至相应的数组中。
注意
- 静态文件存储路径,小心404报错。
- 数据类型没有对应上。由于Element-UI的el-select组件中有change事件,默认参数是value,它的类型是Number;而解析json文件出来的数据类型是String。
感谢作者棋鬼王的博客,https://blog.csdn.net/qq_32113629/article/details/79536177