在開發的很多電商類型的項目中,免不了會遇到三級聯動選擇地址信息,如果單純的使用文本框給用戶選擇,用戶體檢可能就會差很多。今天我給大家整理了關於小程序開發利用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小時之內回復,我們一起進步
