微信小程序省市区三级联动(自定义数据版)可扩展为二级联动

刚有老哥问为啥iPhone 11 不支持省市区三级联动,然后让老哥提供了个代码片段。我用iPhone X看了下 也跑不起来啊。看了下代码逻辑,只有一个省,只写了一个picker-view-column,这搞个啥三级联动。。。然后老哥说了是抠了一部分代码出来的。既然有问题,那我们还是那句话,有需求,然后能搞出来的,咱就花点时间去搞。

然后给老哥实现了该功能,社区可能有其他的方案了,但是再分享下吧,给有需要的童鞋。

效果图:

效果图.gif

额,这个视频转GIF因为社区上传不了大图,所以剪了一部分,具体的效果还是直接工具打开代码片段预览吧~

上代码

wxml:

<view class="address-item" bindtap="pickAddress">
  <view class="item-title">所在地区</view>
  <view class="item-content arrow {{region ? '' : 'item-content_shadow'  }}">{{region||"请选择"}}</view>
</view>
<pop-up visible="{{visible}}" onClose="closePopUp">
  <view slot="content">
    <view class="picker-view">
      <view class="picker-view__pane">
        <text catchtap="cityCancel">取消</text>
        <text catchtap="citySure">确定</text>
      </view>
      <picker-view class="pick-view__group" bindchange="cityChange" value="{{value}}" wx:key="*this">
        <picker-view-column indicator-class="item_active">
          <view wx:for="{{provinces}}" class="picker-item" wx:key="idnex">{{item.name}}</view>
        </picker-view-column>
        <picker-view-column>
          <view wx:for="{{citys}}" class="picker-item" wx:key="">{{item.name}}</view>
        </picker-view-column>
        <picker-view-column>
          <view wx:for="{{areas}}" class="picker-item" wx:key="">{{item.name}}</view>
        </picker-view-column>
      </picker-view>
    </view>
  </view>
</pop-up>

这里有封装一个自定义组件pop-up,是从下往上弹出的的一个效果,已放到代码片段里了,自行查看即可~

接下来是wxss

.address-item {
  min-height: 98rpx;
  display: flex;
  justify-content: flex-start;
  align-items: center;
  border-bottom: 1px solid #f1f1f1;
}

.item-title {
  width: 203rpx;
  color: #4d4c4c;
  font-size: 28rpx;
  height: 98rpx;
  line-height: 98rpx;
}
.item-content {
  width: 520rpx;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 28rpx;
  height: 98rpx;
  line-height: 98rpx;
  color: #4d4c4c;
}
/* 地区级联选择器 */

.picker-view {
  width: 100%;
  display: flex;
  background-color: #fff;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  bottom: 0rpx;
  left: 0rpx;
}

.picker-item {
  line-height: 70rpx;
  margin-left: 5rpx;
  margin-right: 5rpx;
  text-align: center;
}

.picker-view__pane {
  height: 100rpx;
  width: 100%;
  padding: 20rpx 32rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-sizing: border-box;
}

.picker-view__pane text{
  color: red;
  font-size: 30rpx;
}

.pick-view__group {
  width: 96%;
  height: 450rpx;
}

呐,接下来还是重点的js处理。

首先我在本地定义了一个city.js,网上下载的。主要是省市区的数据

var provinces = [{
  "name": "北京市",
  "id": "110000"
}, {
  "name": "天津市",
  "id": "120000"
}, {
  "name": "河北省",
  "id": "130000"
}, {
  "name": "山西省",
  "id": "140000"
}, {
  "name": "内蒙古自治区",
  "id": "150000"
}, {
  "name": "辽宁省",
  "id": "210000"
}]

就不放太多了,具体的可以在代码片段里查看,大家可以自定义数据的id,贴合自己的业务场景。

然后是页面js处理

var app = getApp()
var address = require('./city.js')

var app = getApp()
Page({
  data: {
    address: '', //详细收货地址(四级)
    value: [0, 0, 0], // 地址选择器省市区 暂存 currentIndex
    region: '', //所在地区
    regionValue: [0, 0, 0], // 地址选择器省市区 最终 currentIndex
    provinces: [], // 一级地址
    citys: [], // 二级地址
    areas: [], // 三级地址
    visible: false
  },
  onLoad(options) {
    // 默认联动显示北京
    var id = address.provinces[0].id
    this.setData({
      provinces: address.provinces,
      citys: address.citys[id],
      areas: address.areas[address.citys[id][0].id]
    })
  },
  // 提交时由序号获取省市区id
  getRegionId(type) {
    let value = this.data.regionValue
    let provinceId = address.provinces[value[0]].id
    let townId = address.citys[provinceId][value[1]].id
    let areaId
    if (address.areas.length > 0) {
      areaId = address.areas[townId][value[2]].id
    } else {
      areaId = 0
    }

    if (type === 'provinceId') {
      return provinceId
    } else if (type === 'townId') {
      return townId
    } else {
      return areaId
    }
  },
  closePopUp() {
    this.setData({
      visible: false
    })
  },
  pickAddress() {
    this.setData({
      visible: true,
      value: [...this.data.regionValue]
    })
  },
  // 处理省市县联动逻辑 并保存 value
  cityChange(e) {
    var value = e.detail.value
    let {
      provinces,
      citys
    } = this.data
    var provinceNum = value[0]
    var cityNum = value[1]
    var areaNum = value[2]

    if (this.data.value[0] !== provinceNum) {
      var id = provinces[provinceNum].id
      this.setData({
        value: [provinceNum, 0, 0],
        citys: address.citys[id],
        areas: address.areas[address.citys[id][0].id]
      })
    } else if (this.data.value[1] != cityNum) {
      var id = citys[cityNum].id
      this.setData({
        value: [provinceNum, cityNum, 0],
        areas: address.areas[citys[cityNum].id]
      })
    } else {
      this.setData({
        value: [provinceNum, cityNum, areaNum]
      })
    }
  },
  // 点击地区选择取消按钮
  cityCancel(e) {
    this.setData({
      visible: false
    })
  },
  // 点击地区选择确定按钮
  citySure(e) {
    var value = this.data.value
    this.setData({
      visible: false
    })
    // 将选择的城市信息显示到输入框
    try {
      var region =
        (this.data.provinces[value[0]].name || '') +
        (this.data.citys[value[1]].name || '')
      if (this.data.areas.length > 0) {
        region = region + this.data.areas[value[2]].name || ''
      } else {
        this.data.value[2] = 0
      }
    } catch (error) {
      console.log('adress select something error')
    }

    this.setData({
      region: region,
      regionValue: [...this.data.value]
    })
  }
})

以上就是一个自定义数据版本的省市区三级联动啦,老规矩,结尾放代码片段,大家可自行修改代码扩展,可改为二级联动等。

https://developers.weixin.qq.com/s/1hGLDKm17gdW

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343