zoukankan      html  css  js  c++  java
  • 微信小程序---自定义三级联动

    在开发的很多电商类型的项目中,免不了会遇到三级联动选择地址信息,如果单纯的使用文本框给用户选择,用户体检可能就会差很多。今天我给大家整理了关于小程序开发利用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中引入哦。
  • 相关阅读:
    Android 编程下 Eclipse 恢复被删除的文件
    Android 编程下背景图片适配工具类
    Android 编程下 Managing Your App's Memory
    Android 编程下代码之(QQ消息列表滑动删除)
    Android 编程下 Canvas and Drawables
    Android 编程下 AlarmManager
    Android 编程下去除 ListView 上下边界蓝色或黄色阴影
    Java 编程下字符串的 16 位、32位 MD5 加密
    C#枚举类型和int类型相互转换
    MVC和普通三层架构的区别
  • 原文地址:https://www.cnblogs.com/dreamstartplace/p/10843755.html
Copyright © 2011-2022 走看看