基于ElementUI封装的省市区下拉级联选择
效果
数据
最新省市区JSON数据获取:https://xiangyuecn.github.io/AreaCity-JsSpider-StatsGov/
参数说明
参数 | 说明 |
---|---|
inputNumShow | 下拉框的数量,最多4个 |
defaultAddress | 默认显示省市区 例:[‘安徽’, ‘阜阳’, ‘颍上’, ‘十八里铺’] |
inputInterval | 选择框间的间距 |
组件代码
<template><div>所在地区:<el-select v-show="inputNumShow>=1" v-model="provinceData" clearable @change="provinceChange" filterable placeholder="请选择省"><el-option v-for="item in provinceDataOpt" :key="item.n" :label="item.n" :value="item.n"></el-option></el-select><el-select :style="{marginLeft:inputInterval+'px'}" v-show="inputNumShow>=2" clearable no-data-text="请选择上级" v-model="cityData" @change="cityChange"filterable placeholder="请选择市"><el-option v-for="item in cityDataOpt" :key="item.n" :label="item.n" :value="item.n"></el-option></el-select><el-select :style="{marginLeft:inputInterval+'px'}" v-show="inputNumShow>=3" clearable no-data-text="请选择上级" @change="areaChange" v-model="areaData"filterable placeholder="请选择区县"><el-option v-for="item in areaDataOpt" :key="item.n" :label="item.n" :value="item.n"></el-option></el-select><el-select :style="{marginLeft:inputInterval+'px'}" @change="streetChange" v-show="inputNumShow>=4" clearable no-data-text="请选择上级" v-model="streetData"filterable placeholder="请选择城镇村"><el-option v-for="item in streetDataOpt" :key="item.n" :label="item.n" :value="item.n"></el-option></el-select></div>
</template>
<script>
/*** addressData为省市区的数据,获取地址为:https://xiangyuecn.github.io/AreaCity-JsSpider-StatsGov/* addressData参数说明:* n:名称* y:名称前缀* c:子集*/
import addressData from "./address.json"; //全国省市区街道数据
export default {name: "hsk-addressSel",props:{inputNumShow:{type:Number,default:4,},inputInterval:{type:Number,default:10},defaultAddress:{type:Array,default(){return []}}},data() {return {provinceData: undefined,cityData: undefined,areaData: undefined,streetData: undefined,provinceDataOpt: [],// 省,自治区,直辖市,特别行政区都在其中cityDataOpt: [], // 市数据areaDataOpt: [],// 区数据streetDataOpt: [], //城镇sourceData: null,}},created() {//省市区镇数据处理,将省市区镇数据分离出来this.dataProces()},mounted(){//可能是省市区,也可能是省市,也可能是省市县镇if(typeof(this.defaultAddress[0]) !== "undefined"){this.provinceData = this.defaultAddress[0]this.provinceChange( this.defaultAddress[0])}if(typeof(this.defaultAddress[1]) !== "undefined"){this.cityData = this.defaultAddress[1]this.cityChange(this.defaultAddress[1])}if(typeof(this.defaultAddress[2]) !== "undefined"){this.areaData = this.defaultAddress[2]this.areaChange(this.defaultAddress[2])}if(typeof(this.defaultAddress[3]) !== "undefined"){this.streetData = this.defaultAddress[3]this.streetChange(this.defaultAddress[3])}},methods: {//数据初始化处理dataProces() {//初始化this.provinceDataOpt = []this.cityDataOpt = []this.areaDataOpt = []this.streetDataOpt = []this.sourceData = undefinedthis.cityData = undefinedthis.areaData = undefinedthis.streetData = undefinedthis.sourceData = addressData//递归,为每层添加level,区分省,市,县,镇,并将数据放入指定变量中使用this.addLevel(this.sourceData)},/*** 递归为每个层级添加一个level* 0.(省,自治区,直辖市,特别行政区)、* 1.(市,直辖市,特别行政区)、* 2.(区,县,镇)、* 3. (城,镇,街道)、* 将省市区城镇放入到指定的provinceData,cityData,areaData,streetData*/addLevel(data, level = 0) {for (const key in data) {if (typeof data[key] === 'object' && !Array.isArray(data[key])) {data[key].level = level;if (level === 0) {this.provinceDataOpt.push(data[key])}if ('c' in data[key]) {this.addLevel(data[key].c, level + 1);}}}},/*** 当省份改变选中时触发,获取市,直辖市,行政区,自治区*/provinceChange(e) {this.cityDataOpt = []this.cityData = undefined this.areaData = undefinedthis.areaDataOpt = []this.streetData = undefinedthis.streetDataOpt = []//根据选中项确定市,直辖市,或者特别行政区的数据for (let i = 0; i < this.provinceDataOpt.length; i++) {if (e === this.provinceDataOpt[i].n) {//获取市的内容放入市区数组for (let j in this.provinceDataOpt[i].c) {//获取市,直辖市,行政区,自治区 this.cityDataOpt.push(this.provinceDataOpt[i].c[j])}}} this.$emit("addressChange",[this.provinceData])},/*** 当市区修改的时候触发,获取县,区*/cityChange(e) {this.areaData = undefinedthis.areaDataOpt = []this.streetData = undefinedthis.streetDataOpt = []// 拿到县区选项for (let i = 0; i < this.cityDataOpt.length; i++) {if (e === this.cityDataOpt[i].n) {for (let j in this.cityDataOpt[i].c) {this.areaDataOpt.push(this.cityDataOpt[i].c[j])}}}this.$emit("addressChange",[this.provinceData,this.cityData])},/*** 当前区县修改时触发,获取城镇选项列表*/areaChange(e) {this.streetData = undefinedthis.streetDataOpt = []// 拿到城镇庄村选项for (let i = 0; i < this.areaDataOpt.length; i++) {if (e === this.areaDataOpt[i].n) {for (let j in this.areaDataOpt[i].c) {this.streetDataOpt.push(this.areaDataOpt[i].c[j])}}}this.$emit("addressChange",[this.provinceData,this.cityData,this.areaData])},streetChange(e){this.$emit("addressChange",[this.provinceData,this.cityData,this.areaData,e])}}}
</script><style></style>
父组件使用
<template><div><el-button type="primary" size="mini" @click="xzjiajia">选择++</el-button><el-button type="primary" size="mini" @click="xzjianjian">选择--</el-button><el-button type="primary" size="mini" @click="jjjiajia">间距++</el-button><el-button type="primary" size="mini" @click="jjjianjian">间距--</el-button><div style="margin-top: 20px;"><hsk-address-sel :inputNumShow="inputNumShow" :inputInterval="inputInterval" @addressChange="addressChange":defaultAddress="['安徽', '阜阳', '颍上', '十八里铺']" /></div></div>
</template><script>
import HskAddressSel from '../package/hsk-addressSel/index.vue'
export default {name: "hskAddressSelPage",components: {HskAddressSel},data() {return {inputNumShow: 4,inputInterval: 10,}},methods: {xzjiajia() {this.inputNumShow++},xzjianjian() {this.inputNumShow--},jjjiajia() {this.inputInterval++},jjjianjian() {this.inputInterval--},addressChange(e){console.log("地址:",e)}}
}
</script>
<style></style>