在開發的很多電商類型的項目中,免不了會遇到三級聯動選擇地址信息,如果單純的使用文本框給用戶選擇,用戶體檢可能就會差很多。今天我給大家整理了關於小程序開發利用picker-view組件和animation來實現省市區的三級聯動
效果如圖:


首先我覺的大家需要先去閱讀下小程序有關picker-view和animation相關的api,然后再跟着這篇文章來理一下思路,一定會有深刻的理解。
文檔連接傳送門:
https://developers.weixin.qq.com/miniprogram/dev/component/picker-view.html?search-key=picker-view
省市區mock數據傳送門:
https://github.com/18291907191/tools/blob/master/mock.js
demo目錄如下:


下來,我們就一起從頭到尾來看看三級聯動是如何實現的
第一步:先布局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中引入哦。
有問題記得評論哦,24小時之內回復,我們一起進步