uniapp实现省市区选择联动、vue-elementUI实现省市区选择联动

这篇文章主要是两个部分,一个是uniapp实现的省市区联动,一个是elementUI里面的Cascader 级联选择器实现的


数据格式

下面是后台接口地址列表返回的数据格式
这是省的数据格式
在这里插入图片描述
这是市的数据格式
在这里插入图片描述
这是区、镇的数据格式
在这里插入图片描述
简单来说就是这样,需要嵌套结构,这样才能用到本篇文字的选择

province:[{
  city:[{
     district:[{}]
   }]
 }],

提示:以下是本篇文章正文内容,下面案例可供参考

一、uniapp实现省市区选择联动

1.导入插件

先在uniapp插件市场里面引入地址的插件,我用的这个pickerAddress,感谢这位大佬的插件

2.页面里面使用

1.先在script标签里面引入刚才下载好的插件

import pickerAddress from '@/components/common/Address/pickerAddress.vue'

2.注册插件

components: {
    pickerAddress
},

3.data里面定义一个变量,用来存储选择器选择之后显示的数据

data () {
    return {
    	selectaddress: '点击选择',
    }
}

4.HTML里面使用选择地址的插件

<pickerAddress @change="changeAddress">{{ selectaddress }}</pickerAddress>

5.method里面获取选择的数据(这里面接收的data就是选择的数据)

changeAddress (data) {
      console.log(data)
      this.selectaddress = data.data.join('')	// 这段就是显示我们选择省市区的文字信息
},

3.修改插件里面的代码,用于我们需要的数据

1.template里面的内容

<picker @change="bindPickerChange"
					@columnchange="columnchange"
					:range="array" range-key="name"
					:value="value"
          mode="multiSelector">
    <slot></slot>
  </picker>

2.定义选择的地址名称

let selectVal = ['', '', '']

3.data里面的变量

  data () {
    return {
      value: [0, 0, 0],
      array: [],
      index: 0,
      allAddressArray: [],
      selectAddressId: {
        province_id: '',
        city_id: '',
        district_id: '',
      }
    }
  }

4.created 初始化时调用的方法

created () {
    this.initSelect()
  },

5.method方法

methods: {
    // 初始化地址选项
    initSelect () {
      this.getAllAddress()
    },
    // 地址控件改变控件
    columnchange (d) {
			this.updateSelectIndex(d.detail.column, d.detail.value) // 更新选择索引
        .updateSourceDate() // 更新源数据
        .updateAddressDate() // 更新结果数据
        .$forceUpdate()  // 触发双向绑定
    },
    getAllAddress () {
    	// 这里就是根据接口返回的数据,保存到allAddressArray 变量里面,然后调用this.updateSourceDate这个方法,一定要修改成自己项目调用接口的方法
      this.$R.get(getAllAddressUrl).then(res => {
        this.allAddressArray = res.data.province
        this.updateSourceDate()
      })
    },
    /**
     * 更新源数据
     * */
    updateSourceDate () {
      this.array = []
      this.array[0] = this.allAddressArray.map(obj => {
        return {
          name: obj.name,
          id: obj.id  // 就是这里新增选择的id,因为后台要的参数一般都是id
        }
      })
      // 这里的this.allAddressArray[this.value[0]].city里面的【city】就是根据自己参数修改对应的字段
      this.array[1] = this.allAddressArray[this.value[0]].city.map(obj => {
        return {
          name: obj.name,
          id: obj.id  // 就是这里新增选择的id,因为后台要的参数一般都是id
        }
      })
      // 这里的this.array[2] = this.allAddressArray[this.value[0]].city[this.value[1]].district里面的【city】和【district】就是根据自己参数修改对应的字段
      this.array[2] = this.allAddressArray[this.value[0]].city[this.value[1]].district.map(obj => {
        return {
          name: obj.name,
          id: obj.id  // 就是这里新增选择的id,因为后台要的参数一般都是id
        }
      })
      return this
    },

    /**
     * 更新索引
     * */
    updateSelectIndex (column, value) {
      let arr = JSON.parse(JSON.stringify(this.value))
      arr[column] = value
      if (column === 0) {
        arr[1] = 0
        arr[2] = 0
      }
      if (column === 1) {
        arr[2] = 0
      }
			this.value = arr
      return this
    },

    /**
     * 更新结果数据
     * */
    updateAddressDate () {
      selectVal[0] = this.array[0][this.value[0]].name
      selectVal[1] = this.array[1][this.value[1]].name
      selectVal[2] = this.array[2][this.value[2]].name
      // 这里存起来省市区的id
      this.selectAddressId.province_id = this.array[0][this.value[0]].id
      this.selectAddressId.city_id = this.array[1][this.value[1]].id
      this.selectAddressId.district_id = this.array[2][this.value[2]].id
      return this
    },

    /**
     * 点击确定
     * */
    bindPickerChange (e) {
      this.$emit('change', {
        // 传递参数的时候把选择的id也传过去
        selcecId: this.selectAddressId,
        index: this.value,
        data: selectVal
      })
      return this
    }

  }

4.完整的插件代码

<template>
  <picker @change="bindPickerChange"
					@columnchange="columnchange"
					:range="array" range-key="name"
					:value="value"
          mode="multiSelector">
    <slot></slot>
  </picker>
</template>

<script>
import { getAllAddressUrl } from '@/api/index'

let selectVal = ['', '', '']

export default {
  data () {
    return {
      value: [0, 0, 0],
      array: [],
      index: 0,
      allAddressArray: [],
      selectAddressId: {
        province_id: '',
        city_id: '',
        district_id: '',
      }
    }
  },
  created () {
    this.initSelect()
  },
  methods: {
    // 初始化地址选项
    initSelect () {
      this.getAllAddress()
    },
    // 地址控件改变控件
    columnchange (d) {
			this.updateSelectIndex(d.detail.column, d.detail.value) // 更新选择索引
        .updateSourceDate() // 更新源数据
        .updateAddressDate() // 更新结果数据
        .$forceUpdate()  // 触发双向绑定
    },
    getAllAddress () {
    	// 这里就是根据接口返回的数据,保存到allAddressArray 变量里面,然后调用this.updateSourceDate这个方法,一定要修改成自己项目调用接口的方法
      this.$R.get(getAllAddressUrl).then(res => {
        this.allAddressArray = res.data.province
        this.updateSourceDate()
      })
    },
    /**
     * 更新源数据
     * */
    updateSourceDate () {
      this.array = []
      this.array[0] = this.allAddressArray.map(obj => {
        return {
          name: obj.name,
          id: obj.id  // 就是这里新增选择的id,因为后台要的参数一般都是id
        }
      })
      // 这里的this.allAddressArray[this.value[0]].city里面的【city】就是根据自己参数修改对应的字段
      this.array[1] = this.allAddressArray[this.value[0]].city.map(obj => {
        return {
          name: obj.name,
          id: obj.id  // 就是这里新增选择的id,因为后台要的参数一般都是id
        }
      })
      // 这里的this.array[2] = this.allAddressArray[this.value[0]].city[this.value[1]].district里面的【city】和【district】就是根据自己参数修改对应的字段
      this.array[2] = this.allAddressArray[this.value[0]].city[this.value[1]].district.map(obj => {
        return {
          name: obj.name,
          id: obj.id  // 就是这里新增选择的id,因为后台要的参数一般都是id
        }
      })
      return this
    },

    /**
     * 更新索引
     * */
    updateSelectIndex (column, value) {
      let arr = JSON.parse(JSON.stringify(this.value))
      arr[column] = value
      if (column === 0) {
        arr[1] = 0
        arr[2] = 0
      }
      if (column === 1) {
        arr[2] = 0
      }
			this.value = arr
      return this
    },

    /**
     * 更新结果数据
     * */
    updateAddressDate () {
      selectVal[0] = this.array[0][this.value[0]].name
      selectVal[1] = this.array[1][this.value[1]].name
      selectVal[2] = this.array[2][this.value[2]].name
      // 这里存起来省市区的id
      this.selectAddressId.province_id = this.array[0][this.value[0]].id
      this.selectAddressId.city_id = this.array[1][this.value[1]].id
      this.selectAddressId.district_id = this.array[2][this.value[2]].id
      return this
    },

    /**
     * 点击确定
     * */
    bindPickerChange (e) {
      this.$emit('change', {
        // 传递参数的时候把选择的id也传过去
        selcecId: this.selectAddressId,
        index: this.value,
        data: selectVal
      })
      return this
    }
  }
}

二、vue-elementUI实现省市区选择联动

用这个级联选择器相比来说还是比较简单的

1.使用讲解

1.HTML部分

<el-cascader
    v-model="addressForm.area"
    :options="areaCascaderList"
    :props="areaCascaderProps"
    :placeholder="addressForm.province === ''? '请选择地址': addressForm.province+' / '+addressForm.city+' / '+addressForm.district"
    clearable
    @change="areaCascaderHandleChange">
</el-cascader>

2.data

data () {
    return {
      addressForm: {
        area:'',
        province: '',
        city: '',
        district: '',
      },
      // 地址级联选择器配置
      areaCascaderProps: {
        expandTrigger: 'hover',
        children: 'district',
        label: 'name',
        value: 'id'
      },
      // 地址列表
      areaCascaderList: [],
      // 修改保存下来的地址id
      areaCascaderSelectId: []
    }
  },

3.method部分

// 调用接口返回省市区地址(这个记得要根据自己的接口修改)
async getAreaList () {
   const { data: res } = await this.$http.get(getAllAddressUrl)
   if (res.code !== 200) return this.$message.error(res.msg)
   console.log(res)
   // 统一级联选择器(这一步是为了统一级联选择器的children,可以看看上面接口返回的数据)
   res.data.province.forEach(item => {
     item.district = item.city
   })
   this.areaCascaderList = res.data.province
 },
 // 修改省市区地址级联选择器(这里面保存的就是你选择级联选择器之后的id了)
 areaCascaderHandleChange (value) {
   this.areaCascaderSelectId = value
 },

总结

这篇文章基本上就是这样了,本来只想写一下uniapp实现省市区选择联动,但是考虑到PC端也要用到也顺手写了一下,因为用elementUI级联选择器还是比较简单的,所以没写那么详细,要是有问题欢迎评论留言或者私信,我看到之后会及时进行解答的,要是这篇文章对你有所帮助,希望能够点个赞,谢谢


版权声明:本文为qq_38541936原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。