基于ElementUI封装省市区四级联动下拉选择

基于ElementUI封装的省市区下拉级联选择

效果

基于ElementUI封装省市区级联下拉选择

数据

最新省市区JSON数据获取:https://xiangyuecn.github.io/AreaCity-JsSpider-StatsGov/

基于ElementUI封装省市区级联下拉选择

参数说明

参数说明
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 = undefined
      this.cityData = undefined
      this.areaData = undefined
      this.streetData = undefined
      this.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 = undefined
      this.areaDataOpt = []
      this.streetData = undefined
      this.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 = undefined
      this.areaDataOpt = []
      this.streetData = undefined
      this.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 = undefined
      this.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>
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过使用uview组件实现uni picker省市区三级联动。这个组件可以在uniapp中使用,并且已经封装好了数据的渲染和传递功能。你可以使用template模板语法将数据从页面中传递给uview组件,然后通过Ajax请求从后台获取省市区的数据,将其渲染到picker组件中,并将选择省市区的code码拼接后传递给后台实现需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [使用picker封装省市区三级联动模板](https://download.csdn.net/download/weixin_38642636/16215282)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [uniapp使用uview组件实现省市区三级联动](https://download.csdn.net/download/m0_62676565/85819519)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [uniapp picker组件实现省市区三级联动效果](https://blog.csdn.net/weixin_45356397/article/details/119701421)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值