微信小程序自定义地址组件

本文实例为大家分享了微信小程序自定义地址组件的具体代码,供大家参考,具体内容如下

项目需求

需要调用后台传过来的地址,存储地址时存的是地址的id,所以市面上的地址组件均不符合我的需求,只能自定义一个。

技术选取

picker-view和picker-view-column

核心代码

region.wxml

<!--地址选择器-->
<view wx:if="{{show}}" class="region-picker" catchtap="hidePicker">
  <view class="picker-handle" catchtap>
    <view class="picker-cancel" catchtap="hidePicker">取消</view>
    <view class="picker-confirm" catchtap="chooseRegion">确定</view>
  </view>
  <picker-view class="picker" value="{{regions}}" bindchange="changePicker" catchtap>
    <picker-view-column>
      <view wx:for="{{provinces}}" wx:key="code" class="region-province">{{item.name}}</view>
    </picker-view-column>
    <picker-view-column>
      <view wx:for="{{citys}}" wx:key="code" class="region-city">{{item.name}}</view>
    </picker-view-column>
    <picker-view-column>
      <view wx:for="{{areas}}" wx:key="code" class="region-area">{{item.name}}</view>
    </picker-view-column>
  </picker-view>
</view>

region.less

.region-picker {
  width: 100%;
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  z-index: 2;
  background: rgba(0, 0, 0, 0.6);

  .picker-handle {
    width: 100%;
    height: 72rpx;
    display: flex;
    justify-content: space-between;
    position: absolute;
    bottom: 500rpx;
    left: 0;
    background: #fff;
    box-sizing: border-box;
    padding: 0 30rpx;
    line-height: 72rpx;
    box-shadow: 0 6rpx 12rpx rgba(0, 0, 0, 0.6);

    .picker-cancel,
    .picker-confirm {
      font-size: 30rpx;
    }

    .picker-cancel {
      color: #9E9E9E;
    }

    .picker-confirm {
      color: #018A56;
    }
  }

  .picker {
    width: 100%;
    height: 500rpx;
    position: absolute;
    bottom: 0;
    left: 0;
    background: #fff;

    .region-province,
    .region-city,
    .region-area {
      text-align: center;
      font-size: 24rpx;
    }
  }
}

region.js

const app = getApp();
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    // 是否展示选择器
    showPicker: {
      type: Boolean,
      value: false
    },
    // 初始省市区数组
    initRegions: {
      type: Array,
      value: []
    }
  },

  /**
   * 组件的初始数据
   */
  data: {
    // 当前省市区  0 省  1 市  2 区
    regions: [0, 0, 0],
    // 滑动选择器之前的省市区信息
    oldRegions: [0, 0, 0],
    // 上一次选中的省市区信息
    prevRegions: [0, 0, 0],
    // 省列表
    provinces: [],
    // 市列表
    citys: [],
    // 区列表
    areas: [],
    // 省
    province: {
      name: '',
      code: ''
    },
    // 市
    city: {
      name: '',
      code: ''
    },
    // 区
    area: {
      name: '',
      code: ''
    },
    // 是否展示
    show: false
  },

  lifetimes: {
    attached: function () {

    }
  },

  observers: {
    'showPicker': function (value) {
      if (value) {
        this.setData({
          show: true
        })
        this.initPage();
      } else {
        this.setData({
          show: false
        })
      }
    }
  },

  /**
   * 组件的方法列表
   */
  methods: {
    // 初始化页面
    initPage() {
      let regions = wx.getStorageSync('initRegions') || '';
      if (regions) {
        // 设置省
        app.api.region.index().then(res1 => {
          if (res1.code === 2000) {
            let data1 = res1.data;
            this.setData({
              provinces: data1.map(item => {
                return {
                  name: item.name,
                  code: item.rid
                }
              })
            })
            this.data.provinces.forEach((item, index) => {
              if (item.code === regions[0]) {
                this.setData({
                  ['regions[0]']: index,
                  ['oldRegions[0]']: index,
                  ['prevRegions[0]']: index,
                  province: {
                    name: item.name,
                    code: item.code
                  }
                })
                // 设置市
                app.api.region.index({
                  parent_id: regions[0]
                }).then(async res2 => {
                  if (res2.code === 2000) {
                    res2.data.forEach((item, index) => {
                      this.setData({
                        [`citys[${this.data.citys.length}]`]: {
                          name: item.name,
                          code: item.rid
                        }
                      })
                      if (item.rid === regions[1]) {
                        this.setData({
                          ['regions[1]']: index,
                          ['oldRegions[1]']: index,
                          ['prevRegions[1]']: index,
                          city: {
                            name: item.name,
                            code: item.rid
                          }
                        })
                      }
                    })
                    // 设置区
                    await app.api.region.index({
                      parent_id: regions[1]
                    }).then(res3 => {
                      if (res3.code === 2000) {
                        res3.data.forEach((item, index) => {
                          this.setData({
                            [`areas[${this.data.areas.length}]`]: {
                              name: item.name,
                              code: item.rid
                            }
                          })
                          if (item.rid === regions[2]) {
                            this.setData({
                              ['regions[2]']: index,
                              ['oldRegions[2]']: index,
                              ['prevRegions[2]']: index,
                              area: {
                                name: item.name,
                                code: item.rid
                              },
                            })
                          }
                        })
                      } else if (res3.code === 2001) {
                        app.deletetoken();
                      } else {
                        app.toast(res3.msg, 'none');
                      }
                    })
                  } else if (res2.code === 2001) {
                    app.deletetoken();
                  } else {
                    app.toast(res2.msg, 'none');
                  }
                })
              }
            })
          } else if (res.code === 2001) {
            app.deletetoken();
          } else {
            app.toast(res.msg, 'none');
          }
        })
      } else {
        this.getProvinces();
      }
    },
    /**
     * 获取省
     */
    async getProvinces() {
      await app.api.region.index().then(res => {
        if (res.code === 2000) {
          let data = res.data;
          let provinceList = data.map(item => {
            return {
              name: item.name,
              code: item.rid
            }
          })
          this.setData({
            provinces: provinceList
          })
          this.initCitysAreas();
        } else if (res.code === 2001) {
          app.deletetoken();
        } else {
          app.toast(res.msg, 'none');
        }
      })
    },

    /**
     * 省改变
     * @param {number} code  省id 
     */
    changeProvince(code) {
      app.api.region.index({
        parent_id: code
      }).then(res1 => {
        if (res1.code === 2000) {
          let data1 = res1.data;
          let cityList = data1.map(item => {
            return {
              name: item.name,
              code: item.rid
            }
          })
          this.setData({
            citys: cityList
          })
          app.api.region.index({
            parent_id: this.data.citys[0].code
          }).then(res2 => {
            if (res2.code === 2000) {
              let data2 = res2.data;
              let areaList = data2.map(item => {
                return {
                  name: item.name,
                  code: item.rid
                }
              })
              this.setData({
                areas: areaList
              })
            } else if (res2.code === 2001) {
              app.deletetoken();
            } else {
              app.toast(res2.msg, 'none');
            }
          })
        } else if (res1.code === 2001) {
          app.deletetoken();
        } else {
          app.toast(res1.msg, 'none');
        }
      })
    },

    /**
     * 市改变
     * @param {number} code 市id
     */
    changeCity(code) {
      app.api.region.index({
        parent_id: code
      }).then(res => {
        if (res.code === 2000) {
          let data = res.data;
          let areaList = data.map(item => {
            return {
              name: item.name,
              code: item.rid
            }
          })
          this.setData({
            areas: areaList
          })
        } else if (res.code === 2001) {
          app.deletetoken();
        } else {
          app.toast(res.msg, 'none');
        }
      })
    },

    /**
     * 改变picker
     */
    changePicker(e) {
      let newRegion = e.detail.value;
      for (let i = 0; i < newRegion.length; i++) {
        // 找到改变的那一列
        if (newRegion[i] !== this.data.oldRegions[i]) {
          switch (i + 1) {
            case 1:
              // 省改变了
              this.changeProvince(this.data.provinces[newRegion[i]].code)
              this.setData({
                regions: [newRegion[i], 0, 0],
                oldRegions: [newRegion[i], 0, 0]
              })
              newRegion = [
                newRegion[0], 0, 0
              ]
              break;
            case 2:
              // 市改变了
              this.changeCity(this.data.citys[newRegion[i]].code)
              this.setData({
                regions: [this.data.oldRegions[0], newRegion[i], 0],
                oldRegions: [this.data.oldRegions[0], newRegion[i], 0]
              })
              break;
            case 3:
              // 区改变
              this.setData({
                regions: [this.data.oldRegions[0], this.data.oldRegions[1], newRegion[i]],
                oldRegions: [this.data.oldRegions[0], this.data.oldRegions[1], newRegion[i]]
              })
              break;
          }
        }
      }
    },
    /**
     * 初始化市区列表
     */
    initCitysAreas() {
      // 获取市
      app.api.region.index({
        parent_id: this.data.provinces[this.data.regions[0]].code
      }).then(res1 => {
        if (res1.code === 2000) {
          let data1 = res1.data;
          let cityList = data1.map(item => {
            return {
              name: item.name,
              code: item.rid
            }
          })
          this.setData({
            citys: cityList
          })
          // 获取区
          app.api.region.index({
            parent_id: this.data.citys[this.data.regions[1]].code
          }).then(res2 => {
            if (res2.code === 2000) {
              let data2 = res2.data;
              let areaList = data2.map(item => {
                return {
                  name: item.name,
                  code: item.rid
                }
              })
              this.setData({
                areas: areaList,
                regions: this.data.regions
              })
            } else if (res2.code === 2001) {
              app.deletetoken();
            } else {
              app.toast(res2.msg, 'none');
            }
          })
        } else if (res1.code === 2001) {
          app.deletetoken();
        } else {
          app.toast(res1.msg, 'none');
        }
      })
    },
    /**
     * 隐藏选择器
     */
    hidePicker() {
      this.setData({
        show: false,
        regions: this.data.prevRegions,
        oldRegions: this.data.prevRegions
      })
    },
    /**
     * 确定选择地址
     */
    chooseRegion() {
      this.setData({
        province: {
          name: this.data.provinces[this.data.regions[0]].name,
          code: this.data.provinces[this.data.regions[0]].code
        },
        city: {
          name: this.data.citys[this.data.regions[1]].name,
          code: this.data.citys[this.data.regions[1]].code
        },
        area: {
          name: this.data.areas[this.data.regions[2]].name,
          code: this.data.areas[this.data.regions[2]].code
        },
        prevRegions: this.data.regions,
      })
      this.triggerEvent("chooseRegion", {
        initRegions: [this.data.province.code, this.data.city.code, this.data.area.code],
        region: this.data.province.name + ' ' + this.data.city.name + ' ' + this.data.area.name
      })
      wx.setStorageSync('initRegions', [this.data.province.code, this.data.city.code, this.data.area.code]);
      this.hidePicker();
    },
  }
})

使用

wxml

<region showPicker="{{show.picker}}" initRegions="{{initRegions}}" bind:chooseRegion="chooseRegion"></region>

js

// pages/settled/settled.js
const app = getApp();
Page({

  /**
   * 页面的初始数据
   */
  data: {
    // 选中的省市区id数组
    initRegions: [],
    // 常住地址
    region: '',
    // 展示控制
    show: {
      picker: false, // 地址选择器
    }
  },

  /**
   * 监听页面卸载
   */
  onUnload: function() {
    wx.removeStorageSync('initRegions');
  },
  /**
   * 展示常住地址选择器
   */
  showPicker() {
    this.setData({
      ['show.picker']: true
    })
  },

  /**
   * 选择常住地址
   */
  chooseRegion(e) {
    this.setData({
      initRegions: e.detail.initRegions,
      region: e.detail.region
    })
  }
})

效果

参考文档

picker-view | 微信开放文档
picker-view-column | 微信开放文档

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 微信小程序 ecshop地址三级联动实现实例代码

    微信小程序 ecshop地址3级联动实现实例代码 picker标签,官方给出的实例: <view class="section"> <view class="section__title">地区选择器</view> <picker bindchange="bindPickerChange" value="{{index}}" range="{{array}}">

  • 微信小程序实现获取准确的腾讯定位地址功能示例

    本文实例讲述了微信小程序实现获取准确的腾讯定位地址功能.分享给大家供大家参考,具体如下: 官方参考文档:https://lbs.qq.com/qqmap_wx_jssdk/index.html 逆地址解析(坐标位置描述) 1. 申请开发者密钥(key)与设置 个人使用:登录,点击"key管理",进入设置,选择"WebServiceAPI",如果没有小程序ID,勾选"授权IP",如果有小程序ID,勾选"域名白名单",且勾选&qu

  • 微信小程序实现选择地址省市区三级联动

    本文实例为大家分享了微信小程序实现选择地址省市区三级联动的具体代码,供大家参考,具体内容如下 微信原生地址API,缺少省市区code,因此自己写了一个收货地址 思路:在onload预先加载全部省和第一个省的全部市和区,加载全部会导致几秒的事件阻塞.点击选择地址弹窗后,按需加载操作,滑动省加载对应的市和第一个市对应的区,滑动市加载区,滑动区只更改区的值 onLoad: function(options) { var that = this; // 此文件为全部省以及第一个省的市和区 var cit

  • 微信小程序如何获取用户收货地址

    获取用户收货地址需要用户点击授权,所以有两种情况,确认授权.取消授权. 情况一,用户第一次访问用户地址授权,并且点击确定授权. 情况二,用户点击取消授权后,再次获取授权 流程: (代码逻辑整理) 1.点击事件触发函数,获取用户当前设置 2.根据用户当前设置中的用户授权结果,判断是否包含收货地址授权 3.如果包含收货地址授权并且没有取消过收货地址授权,直接调用wx.chooseAddress(),获取用户收货地址. 4.取消过收货地址授权,调用wx.openSetting(),调起客户端小程序设置

  • 微信小程序三级联动地址选择器的实例代码

    本文介绍了微信小程序三级联动地址选择器的实例代码,分享给大家,有需要的可以一起了解一下 在一些电商类的小程序中,地址选择这个功能一般是必备的,一般的收货信息都需要有一个能选择省市县的控件,当然也有些人为了省事就直接写了一个供输入的input,那么这样做的缺点不言而喻,而且用户体验也不是那么的好,今天的这篇文章就分享一下微信小程序地址选择的实现.省市县的数据以及区域码可以从国家统计局查询到,具体可以自己搜一下.照例先上源码和效果图 源码传送门 picker和picker-view组件 在正式介绍实

  • 微信小程序实现省市区三级地址选择

    国际惯例先上效果图: 省市区三级联动,选择省自动刷新市,选择市自动刷新区,点击取消自动返回上一级重新选择,点击确定,保存地址. 数据库 这份数据库是某天在网上逛到的,当时未记录出处,直接贴出给读者使用,实在不妥,此处仅贴出表结构,方便大家交流学习.如有读者了解此份数据出处,烦请留言,谢谢! 数据表结构如下: 部分使用到的字段信息: id:唯一标识每一个数据 name:地区名 parent_id:上级地区的id,若parent_id = 0 ,表示无上级信息,当前即为最高行政区. extra:主要

  • 微信小程序开发实现的IP地址查询功能示例

    本文实例讲述了微信小程序开发实现的IP地址查询功能.分享给大家供大家参考,具体如下: 微信小程序 开发 参考   https://mp.weixin.qq.com/debug/wxadoc/dev/component/ search.wxml <view class="container"> <view class="page-body"> <view class="weui-search-bar {{searchFocusC

  • 微信小程序在地图选择地址并返回经纬度简单示例

    本文实例讲述了微信小程序在地图选择地址并返回经纬度功能.分享给大家供大家参考,具体如下: 微信小程序的地址管理中,经常需要获取地址的详细地址信息和地址经纬度信息 wxml文件部分代码: <button bindtap="mapView" style="margin:10px">查看地图</button> js文件主要功能代码: mapView:function(){ var that = this wx.chooseLocation({ su

  • 微信小程序 可搜索的地址选择实现详解

    这篇文章主要介绍了微信小程序 可搜索的地址选择实现详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 最终实现效果: 效果实现步骤 新建index文件夹 index.wxml <!--pages/index/index.wxml--> <view class='container'> <view bindtap='onChangeAddress'> <input value="{{address}}&q

  • 微信小程序 (地址选择1)--选取搜索地点并显示效果

    效果:(直接复制代码,可查看效果) 可以通过拖动地图,搜索地址,选择地址,并将地址值传给文本框 进入以下界面 点击确定后. 代码如下: wxml: <view class="box2"> <view class="box2_left">收货地址</view> <input type="text" class="box2_right" placeholder="请选择收货地址&

随机推荐