微信小程序---自定义三级联动

在开发的不少电商类型的项目中,免不了会遇到三级联动选择地址信息,若是单纯的使用文本框给用户选择,用户体检可能就会差不少。今天我给你们整理了关于小程序开发利用picker-view组件和animation来实现省市区的三级联动
效果如图:
 
首先我觉的你们须要先去阅读下小程序有关picker-view和animation相关的api,而后再跟着这篇文章来理一下思路,必定会有深入的理解。
 
DOMO以下:
第一步:先布局wml页面:
 1 <view class="picker-view" animation="{{animationAddressMenu}}" style="visibility:{{addressMenuIsShow ? 'visible':'hidden'}}">
 2     <!-- 确认取消按钮 -->
 3     <view class='btn'>
 4         <text catchtap="cityCancel">取消</text>
 5         <text style="float: right" catchtap="citySure">肯定</text>
 6     </view>
 7     <!-- 选择地址 -->
 8     <picker-view class='cont' bindchange="cityChange" value="{{value}}" wx:key="">
 9     <!---->
10         <picker-view-column>
11             <view wx:for="{{provinces}}" class="picker-item" wx:key="{{index}}">{{item.name}}</view>
12         </picker-view-column>
13 <!---->
14         <picker-view-column>
15             <view wx:for="{{citys}}" class="picker-item" wx:key="index">{{item.name}}</view>
16         </picker-view-column>
17 <!---->
18         <picker-view-column>
19             <view wx:for="{{areas}}" class="picker-item" wx:key="index">{{item.name}}</view>
20         </picker-view-column>
21     </picker-view>
22 </view>
23   
24 <button bindtap='select' class='select'>地址选择</button>
25 <view class='address'>{{areaInfo}}</view>

 

picker-view做为外层标签包裹picker-view-column,有几个picker-view-column就有几列数据。html

 

第二步:设置其样式:git

 1 .picker-view {
 2     width: 100%;
 3     display: flex;
 4     z-index:12;
 5     background-color: #fff;
 6     background: rgba(0, 0, 0, .2);
 7     flex-direction: column;
 8     justify-content: center;
 9     align-items: center;
10     position: fixed;
11     bottom: 0;
12     left: 0rpx;
13     height: 40vh;
14 }
15 .btn {
16     width: 100%;
17     height: 90rpx;
18     padding: 0 24rpx;
19     box-sizing: border-box;
20     line-height: 90rpx;
21     text-align: center;
22     display: flex;
23     background: rgba(255,255,255,.8);
24     justify-content: space-between;
25 }
26 .cont {
27     width: 100%;
28     height: 389rpx;
29 }
30 .picker-item {
31     line-height: 70rpx;
32     margin-left: 5rpx;
33     margin-right: 5rpx;
34     text-align: center;
35 }
36 .address {
37     width: 100%;
38     height: 90rpx;
39     line-height: 90rpx;
40     text-align: center;
41     border-bottom: 1rpx solid #f1f1f1;
42 }

 

wxss中值得注意的是vh单位: 
    vh:viewpoint height,视窗高度,1vh等于视窗高度的1%。
 
第三步:实现省市区选择的业务逻辑和动画画出的实现:
 1 var address = require("../mock.js")  2 Page({  3  /**  4  * 控件当前显示的数据  5  * provinces:全部省份  6  * citys 选择省对应的全部市,  7  * areas 选择市对应的全部区  8  * areaInfo:点击肯定时选择的省市县结果  9  * animationAddressMenu:动画  10  * addressMenuIsShow:是否可见  11  */  12  data: {  13  animationAddressMenu: {},  14  addressMenuIsShow: false,  15  value: [0, 0, 0],  16  provinces: [],  17  citys: [],  18  areas: [],  19  areaInfo: ''  20  },  21   
 22  /**  23  * 生命周期函数--监听页面加载  24  */  25  onLoad: function (options) {  26  // 默认联动显示北京  27  var id = address.provinces[0].id  28  this.setData({  29  provinces: address.provinces,  30  citys: address.citys[id],  31  areas: address.areas[address.citys[id][0].id],  32  })  33  },  34  // 点击所在地区弹出选择框  35  select: function (e) {  36  // 若是已经显示,不在执行显示动画  37  if (this.data.addressMenuIsShow) {  38  return false  39  } else {  40  // 执行显示动画  41  this.startAddressAnimation(true)  42  }  43  },  44  // 执行动画  45  startAddressAnimation: function (isShow) {  46  if (isShow) {  47  // vh是用来表示尺寸的单位,高度全屏是100vh  48  this.animation.translateY(0 + 'vh').step()  49  } else {  50  this.animation.translateY(40 + 'vh').step()  51  }  52  this.setData({  53  animationAddressMenu: this.animation.export(),  54  addressMenuIsShow: isShow,  55  })  56  },  57  // 点击地区选择取消按钮  58  cityCancel: function (e) {  59  this.startAddressAnimation(false)  60  },  61  // 点击地区选择肯定按钮  62  citySure: function (e) {  63  var that = this  64  var city = that.data.city  65  var value = that.data.value  66  this.startAddressAnimation(false)  67  // 将选择的城市信息显示到输入框  68  var areaInfo = that.data.provinces[value[0]].name + '·' + that.data.citys[value[1]].name + '·' + that.data.areas[value[2]].name  69  that.setData({  70  areaInfo: areaInfo,  71  })  72  },  73  // 处理省市县联动逻辑  74  cityChange: function (e) {  75  var value = e.detail.value  76  var provinces = this.data.provinces  77  var citys = this.data.citys  78  var areas = this.data.areas  79  var provinceNum = value[0]  80  var cityNum = value[1]  81  var countyNum = value[2]  82  // 若是省份选择项和以前不同,表示滑动了省份,此时市默认是省的第一组数据,  83  if (this.data.value[0] != provinceNum) {  84  var id = provinces[provinceNum].id  85  this.setData({  86  value: [provinceNum, 0, 0],  87  citys: address.citys[id],  88  areas: address.areas[address.citys[id][0].id],  89  })  90  } else if (this.data.value[1] != cityNum) {  91  // 滑动选择了第二项数据,即市,此时区显示省市对应的第一组数据  92  var id = citys[cityNum].id  93  this.setData({  94  value: [provinceNum, cityNum, 0],  95  areas: address.areas[citys[cityNum].id],  96  })  97  } else {  98  // 滑动选择了区  99  this.setData({ 100  value: [provinceNum, cityNum, countyNum] 101  }) 102  } 103  }, 104  onShow: function () { 105  var animation = wx.createAnimation({ 106  duration: 500, 107  timingFunction: 'linear', 108  }) 109  this.animation = animation 110  } 111 })

 

难点:
    主要是再实现省市区联动的时候,须要根据省份的id去查找对应的市,而后根据选择的市查找对应的区。这里比较复杂,提供方法:多打断点,明确输出结果是什么。
    动画的实现:经过实例化对象,再onShow中将animation放到全局中,而后建立方法,将方法经过 this.animation.translateY(0 + 'vh').step()导出,而后经过将 this.setData({animationAddressMenu: this.animation.export()})导出就能够了,不过,别忘了在wxml中引入哦。
相关文章
相关标签/搜索