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


    在开发的很多电商类型的项目中,免不了会遇到三级联动选择地址信息,如果单纯的使用文本框给用户选择,用户体检可能就会差很多。今天我给大家整理了关于小程序开发利用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就有几列数据。

    第二步:设置其样式:

     1 .picker-view {
     2      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      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      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      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中引入哦。
  • 相关阅读:
    第八章
    第十章
    第九章
    第七章
    第六章
    第五章
    第四章心得
    第二章心得
    第三章心得
    第一章心得
  • 原文地址:https://www.cnblogs.com/dreamstartplace/p/10843755.html
Copyright © 2020-2023  润新知