首页 > 网站 > 帮助中心 > 正文

基于Vue+ElementUI的省市区地址选择通用组件

2024-07-09 22:41:39
字体:
来源:转载
供稿:网友

一、缘由

在项目开发过程中,有一个需求是省市区地址选择的功能,一开始想的是直接使用静态地址资源库本地打包,但这种方式不方便维护,于是放弃。后来又想直接让后台返回全部地址数据,然后使用级联选择器进行选择,但发现数据传输量有点大且处理过程耗时,于是又摒弃了这种方法。最后还是决定采用异步的方式进行省市区地址选择,即先查询省份列表,然后根据选择的省份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) {   let a = (item) => {    this.$http({     method: 'get',     url: this.API.city + '/' + value[0],    }).then(res => {     item.cities = res.data.body.map(ite => {      return {       value: ite.cityCode,       label: ite.cityName,       cities: []      }     })     if(value.length === 2){ // 如果传入的value.length===2 && 先执行的a(),说明是传入了areaCode,需要初始化多选框      b(item)     }    }).finally(_ => {    })   }   let b = (item) => {    if (value.length === 2) {     item.cities.find(ite => {      if (ite.value === value[1]) {       if (!ite.cities.length) {        this.$http({         method: 'get',         url: this.API.area + '/' + value[1]        }).then(res => {         ite.cities = res.data.body.map(ite => {          return {           value: ite.areaCode,           label: ite.areaName,          }         })        }).finally(_ => {        })       }      }     })    }   }   this.city.options.find(item => {    if (item.value === value[0]) {     if (item.cities.length) {      b(item)     } else {      a(item)     }     return true    }   })  },  getCityCode () {   return this.cityValue[2]  },  reset () {   this.cityValue = []  },  cityChange (value) {   if (value.length === 3) {    this.$emit('cityChange', value[2])   } else {    this.$emit('cityChange', null)   }  } }, watch: {  areaCode: {   deep: true,   immediate: true,   handler (newVal) {    if (newVal) {     this.getCodeByAreaCode(newVal)    } else {     this.$nextTick(() => {      this.reset()     })    }   }  } }}</script><style lang="less" scoped></style>
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表