在开发的很多电商类型的项目中,免不了会遇到三级联动选择地址信息,如果单纯的使用文本框给用户选择,用户体检可能就会差很多。今天我给大家整理了关于小程序开发利用picker-view组件和animation来实现省市区的三级联动
效果如图:
 
首先我觉的大家需要先去阅读下小程序有关picker-view和animation相关的api,然后再跟着这篇文章来理一下思路,一定会有深刻的理解。
 
DOMO如下:
第一步:先布局wml页面:
 <view class="picker-view" animation="{{animationAddressMenu}}" style="visibility:{{addressMenuIsShow ? 'visible':'hidden'}}">
<!-- 确认取消按钮 -->
<view class='btn'>
<text catchtap="cityCancel">取消</text>
<text style="float: right" catchtap="citySure">确定</text>
</view>
<!-- 选择地址 -->
<picker-view class='cont' bindchange="cityChange" value="{{value}}" wx:key="">
<!-- 省 -->
<picker-view-column>
<view wx:for="{{provinces}}" class="picker-item" wx:key="{{index}}">{{item.name}}</view>
</picker-view-column>
<!-- 市 -->
<picker-view-column>
<view wx:for="{{citys}}" class="picker-item" wx:key="index">{{item.name}}</view>
</picker-view-column>
<!-- 区 -->
<picker-view-column>
<view wx:for="{{areas}}" class="picker-item" wx:key="index">{{item.name}}</view>
</picker-view-column>
</picker-view>
</view> <button bindtap='select' class='select'>地址选择</button>
<view class='address'>{{areaInfo}}</view>

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

第二步:设置其样式:

 .picker-view {
width: 100%;
display: flex;
z-index:12;
background-color: #fff;
background: rgba(0, 0, 0, .2);
flex-direction: column;
justify-content: center;
align-items: center;
position: fixed;
bottom: 0;
left: 0rpx;
height: 40vh;
}
.btn {
width: 100%;
height: 90rpx;
padding: 0 24rpx;
box-sizing: border-box;
line-height: 90rpx;
text-align: center;
display: flex;
background: rgba(255,255,255,.8);
justify-content: space-between;
}
.cont {
width: 100%;
height: 389rpx;
}
.picker-item {
line-height: 70rpx;
margin-left: 5rpx;
margin-right: 5rpx;
text-align: center;
}
.address {
width: 100%;
height: 90rpx;
line-height: 90rpx;
text-align: center;
border-bottom: 1rpx solid #f1f1f1;
}
wxss中值得注意的是vh单位: 
    vh:viewpoint height,视窗高度,1vh等于视窗高度的1%。
 
第三步:实现省市区选择的业务逻辑和动画画出的实现:
 var address = require("../mock.js")
Page({
/**
* 控件当前显示的数据
* provinces:所有省份
* citys 选择省对应的所有市,
* areas 选择市对应的所有区
* areaInfo:点击确定时选择的省市县结果
* animationAddressMenu:动画
* addressMenuIsShow:是否可见
*/
data: {
animationAddressMenu: {},
addressMenuIsShow: false,
value: [0, 0, 0],
provinces: [],
citys: [],
areas: [],
areaInfo: ''
}, /**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
// 默认联动显示北京
var id = address.provinces[0].id
this.setData({
provinces: address.provinces,
citys: address.citys[id],
areas: address.areas[address.citys[id][0].id],
})
},
// 点击所在地区弹出选择框
select: function (e) {
// 如果已经显示,不在执行显示动画
if (this.data.addressMenuIsShow) {
return false
} else {
// 执行显示动画
this.startAddressAnimation(true)
}
},
// 执行动画
startAddressAnimation: function (isShow) {
if (isShow) {
// vh是用来表示尺寸的单位,高度全屏是100vh
this.animation.translateY(0 + 'vh').step()
} else {
this.animation.translateY(40 + 'vh').step()
}
this.setData({
animationAddressMenu: this.animation.export(),
addressMenuIsShow: isShow,
})
},
// 点击地区选择取消按钮
cityCancel: function (e) {
this.startAddressAnimation(false)
},
// 点击地区选择确定按钮
citySure: function (e) {
var that = this
var city = that.data.city
var value = that.data.value
this.startAddressAnimation(false)
// 将选择的城市信息显示到输入框
var areaInfo = that.data.provinces[value[0]].name + '·' + that.data.citys[value[1]].name + '·' + that.data.areas[value[2]].name
that.setData({
areaInfo: areaInfo,
})
},
// 处理省市县联动逻辑
cityChange: function (e) {
var value = e.detail.value
var provinces = this.data.provinces
var citys = this.data.citys
var areas = this.data.areas
var provinceNum = value[0]
var cityNum = value[1]
var countyNum = 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, countyNum]
})
}
},
onShow: function () {
var animation = wx.createAnimation({
duration: 500,
timingFunction: 'linear',
})
this.animation = animation
}
})
难点:
    主要是再实现省市区联动的时候,需要根据省份的id去查找对应的市,然后根据选择的市查找对应的区。这里比较复杂,提供方法:多打断点,明确输出结果是什么。
    动画的实现:通过实例化对象,再onShow中将animation放到全局中,然后创建方法,将方法通过 this.animation.translateY(0 + 'vh').step()导出,然后通过将 this.setData({animationAddressMenu: this.animation.export()})导出就可以了,不过,别忘了在wxml中引入哦。

微信小程序---自定义三级联动的更多相关文章

  1. 微信小程序 实现三级联动-省市区

    github项目地址   https://github.com/z1511676208/chooseAddr 序:项目中需要用到三级联动,自己试着写了下,也查了一些资料,现在把这个记录一下,里面地区数 ...

  2. uni-app 微信小程序 picker 三级联动

    之前做过一个picker的三级联动功能,这里分享代码给大家 具体代码: // An highlighted block <template> <view> <picker ...

  3. 微信小程序——自定义导航栏

    微信头部导航栏可能通过json配置: 但是有时候我们项目需求可能需要自定义头部导航栏,如下图所示: 现在具体说一下实现步骤及方法: 步骤: 1.在 app.json 里面把 "navigat ...

  4. 微信小程序自定义弹窗wcPop插件|仿微信弹窗样式

    微信小程序自定义组件弹窗wcPop|小程序消息提示框|toast自定义模板弹窗 平时在开发小程序的时候,弹窗应用场景还是蛮广泛的,但是微信官方提供的弹窗比较有局限性,不能自定义修改.这个时候首先想到的 ...

  5. NO--14 微信小程序,左右联动二

    上一篇讲解了左=>右联动,那个还比较简单,本篇写剩下比较核心的部分,也是本次开发过程中遇到最难的部分,右=>左联动,先简单看一下演示   右左联动.gif 一.关键技术: (1) 小程序 ...

  6. 微信小程序自定义 tabbar

    一定的需求情况下,无法使用小程序原生的 tabbar 的时候,需要自行实现一个和 tabbar 功能一模一样的自制组件. 查阅了海量的博客和文档之后,亲自踩坑.总结了三种在不使用微信小程序原生 tab ...

  7. 微信小程序-自定义底部导航

    代码地址如下:http://www.demodashi.com/demo/14258.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...

  8. 微信小程序自定义tabbar的实现

    微信小程序自定义tabbar的实现 目的:当采用微信的自定义tabbar组件的时候,切换的时候会出现闪屏的效果:当使用微信默认的tabbar的时候,限制了tabbar的数量以及灵活配置. 方案:自己动 ...

  9. 微信小程序 自定义导航组件 nav头部 全面屏设计

    nav-dynamic 微信小程序自定义nav头部组件:适配全面屏设计: 实现功能 初始进入页面时,展示初始状态下的nav样式: 页面滚动时,监听页面滚动事件,展示滚动状态下的nav样式: 根据配置字 ...

随机推荐

  1. HDU 2674

    0 <= N<=10^9 看到这个数据范围知道常规方法肯定做不出来. 不过一想想既然是mod2009,是不是只要其中含有一个2009,那么其结果一定是0了呢 说了这里思路,就是看什么时候出 ...

  2. JVM基础--JVM参数之堆栈空间配置

    目录 堆配置 年轻代 Eden区 永久代(JDK1.7) 元空间(JDK1.8) 栈空间 直接内存 总结 参考资料 JVM系列目录 JVM 中最重要的一部分就是堆空间了,基本上大多数的线上 JVM 问 ...

  3. java面向接口编程之适配器模式

    使用一个现成的类,但是它的接口不完全符合你的需求,我只想要它其中的一个方法,不想覆写其他的方法. 比如,窗体有变大,变小,关闭的行为,但是我现在只需要关闭行为;   package reviewDem ...

  4. notepad2正则表达式替换字符串

    例子: 1-385-463-3226替换成13854633226 Ctrl+H开启替换,选中'regular expression search'或者正则表达式: 上面输入:1-(.*)-(.*)-( ...

  5. Python--day46--上节内容回顾及补充

    1,union(把两张表连起来,以上下的方式):具有自动去重的功能,有相同的就去掉. 结果: 2,union all就没有去重的功能 3,临时表,指定映射,条件,三元运算

  6. P1107 栈

    题目描述 背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即 pop(从栈顶弹出一个元素)和 push(将一个元素进栈). 栈的重要性不言 ...

  7. WPF 使用 Composition API 做高性能渲染

    在 WPF 中很多小伙伴都会遇到渲染性能的问题,虽然 WPF 的渲染可以甩浏览器渲染几条街,但是还是支持不了游戏级的渲染.在 WPF 使用的 DX 只是优化等级为 9 和 DX 9 差不多的性能,微软 ...

  8. linux 内核协助的探测

    Linux 内核提供了一个低级设施来探测中断号. 它只为非共享中断, 但是大部分能够在共 享中断状态工作的硬件提供了更好的方法来尽量发现配置的中断号.这个设施包括 2 个函 数, 在<linux ...

  9. JUnit 单元测试断言推荐 AssertJ

    文章转自:http://sgq0085.iteye.com/blog/2030609 前言 由于JUnit的Assert是公认的烂API,所以不推荐使用,目前推荐使用的是AssertJ. Assert ...

  10. eslint的使用和配置

    eslint的使用和配置 什么是eslint ESLint 是在 ECMAScript/JavaScript 代码中识别和报告模式匹配的工具,它的目标是保证代码的一致性和避免错误.在许多方面,它和 J ...