在一(yi)(yi)些電(dian)商類的(de)(de)小(xiao)程序中,地(di)址(zhi)選(xuan)(xuan)擇(ze)這個(ge)功能一(yi)(yi)般是(shi)必(bi)備的(de)(de),一(yi)(yi)般的(de)(de)收貨信息都需要有一(yi)(yi)個(ge)能選(xuan)(xuan)擇(ze)省(sheng)市(shi)縣的(de)(de)控件,當然(ran)也有些人為了省(sheng)事(shi)就直接(jie)寫了一(yi)(yi)個(ge)供(gong)輸入(ru)的(de)(de)input,那(nei)(nei)么這樣做的(de)(de)缺點(dian)不言而喻(yu),而且用戶體驗(yan)也不是(shi)那(nei)(nei)么的(de)(de)好(hao),今天的(de)(de)這篇文章就分享一(yi)(yi)下(xia)微(wei)信小(xiao)程序地(di)址(zhi)選(xuan)(xuan)擇(ze)的(de)(de)實現。省(sheng)市(shi)縣的(de)(de)數據(ju)以(yi)及區域碼(ma)可(ke)以(yi)從國家統計局(ju)查詢(xun)到,具體可(ke)以(yi)自(zi)己搜(sou)一(yi)(yi)下(xia)。照(zhao)例先上源碼(ma)和效果(guo)圖
在正式介紹實現之前,我們需要先來介紹下這兩個組件,picker這個組件在前面的文章有簡單介紹過,它是從底部彈起的滾動選擇器,可以通過設置type的值來實現日期選擇,時間選擇以及普通的選擇器,如果我們想實現上圖三級聯動地址選擇效果,發現實現起來很困難,應該說是不能實現,因為picker普通選擇器是只能有一列,如果想這實現三列的效果就需要另辟蹊徑了。
既然是另辟蹊徑(jing),自(zi)然就會想(xiang)到picker-view,該組件(jian)是一個嵌入頁面的(de)滾動選擇器,該組件(jian)中(zhong)可以放(fang)置(zhi)多個picker-view-column,并(bing)且只能放(fang)置(zhi)picker-view-column,其它組件(jian)是不會顯示的(de),每(mei)一個picker-view-column就是一列(lie)。
picker-view有幾(ji)個(ge)重要的(de)屬性,value是一個(ge)數(shu)組(zu)類型(xing),數(shu)組(zu)中的(de)數(shu)字依次表示 picker-view 內的(de) picker-view-colume 選擇的(de)第(di)幾(ji)項(xiang)(下標從 0 開(kai)(kai)始(shi)(shi)),數(shu)字大于 picker-view-column 可(ke)選項(xiang)長度(du)時,選擇最后一項(xiang)。indicator-style和(he)indicator-class可(ke)以設(she)置選擇器中間選中框的(de)樣式,他有一個(ge)事件bindchange,當我(wo)們滾動item時選擇的(de)item數(shu)據發生變(bian)化就會觸發這個(ge)函數(shu),并且可(ke)以通過event.detai.vaule(和(he)上面(mian)介紹vaule含義相(xiang)同)獲(huo)取當前選擇的(de)是第(di)幾(ji)項(xiang)(下標從 0 開(kai)(kai)始(shi)(shi))。而對于picker-view-column高度(du)會自動設(she)置成(cheng)與(yu)picker-view的(de)選中框的(de)高度(du)一致。
省市縣數據(ju)(ju)文件存儲了(le)地址選擇所(suo)需要用到的數據(ju)(ju),主要是區域碼和名字,然后通過下面代(dai)碼將數據(ju)(ju)暴露出去,以供使用
module.exports = {
citys,
provinces,
areas
}
wxml文(wen)件(jian)實現
<view class="picker-view" animation="{{animationAddressMenu}}" style="visibility:{{addressMenuIsShow ? 'visible':'hidden'}}">
<view style="height:10% ;width:95%;margin-top:10rpx">
<text catchtap="cityCancel">取消</text>
<text style="float: right" catchtap="citySure">確定</text>
</view>
<!--"可以顯示默認的城市,使用后級聯選擇城市反應很慢就不使用了-->
<picker-view style="width: 100%; height: 300px;" bindchange="cityChange" value="{{value}}" wx:key="">
<picker-view-column>
<view wx:for="{{provinces}}" class="picker-item">
{{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{citys}}" class="picker-item" wx:key="">
{{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{{areas}}" class="picker-item" wx:key="">
{{item.name}}</view>
</picker-view-column>
</picker-view>
</view>
主要就是(shi)上面(mian)有一(yi)個(ge)取消和(he)確(que)定供用戶點擊確(que)認選擇,以及picker-view 中包含三個(ge)picker-view-column組件(jian),分(fen)別對(dui)應(ying)顯(xian)示省市區,provinces,citys,areas是(shi)對(dui)應(ying)的數據(ju),animation是(shi)選擇控(kong)件(jian)可(ke)見或者不可(ke)見時(shi)的過渡動畫。
樣(yang)式wxss文件(jian)
.picker-view {
width: 100%;
display: flex;
z-index:12;
background-color: #fff;
flex-direction: column;
justify-content: center;
align-items: center;
position: fixed;
bottom: 0rpx;
left: 0rpx;
height: 40vh;
}
.picker-item {
line-height: 70rpx;
margin-left: 5rpx;
margin-right: 5rpx;
text-align: center;
}
在(zai)js中(zhong)我(wo)們(men)在(zai)data中(zhong)加入數據
/**
* 控件當前顯示的數據
* provinces:所有省份
* citys 選擇省對應的所有市,
* areas選擇市對應的所有區
* areaInfo:點擊確定時選擇的省市縣字符拼接
* animationAddressMenu:動畫
* addressMenuIsShow:是否可見
*/
data: {
animationAddressMenu: {},
addressMenuIsShow: false,
value: [0, 0, 0],
provinces: [],
citys: [],
areas: [],
areaInfo:''
},
最重要的是在js文件開始處引入(ru)數據文件
var address = require('../../utils/city.js')
onLoad中(zhong)初始化數據,默認顯(xian)示北京
// 默認聯動顯示北京
var id = address.provinces[0].id
this.setData({
provinces: address.provinces,
citys: address.citys[id],
areas: address.areas[address.citys[id][0].id],
})
事件的處理邏(luo)輯(ji):
// 點擊所在地區彈出選擇框
selectDistrict: function (e) {
var that = this
// 如果已經顯示,不在執行顯示動畫
if (that.data.addressMenuIsShow) {
return
}
// 執行顯示動畫
that.startAddressAnimation(true)
},
// 執行動畫
startAddressAnimation: function (isShow) {
console.log(isShow)
var that = this
if (isShow) {
// vh是用來表示尺寸的單位,高度全屏是100vh
that.animation.translateY(0 + 'vh').step()
} else {
that.animation.translateY(40 + 'vh').step()
}
that.setData({
animationAddressMenu: that.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
that.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,
})
},
// 點擊蒙版時取消組件的顯示
hideCitySelected: function (e) {
console.log(e)
this.startAddressAnimation(false)
},
// 處理省市縣聯動邏輯
cityChange: function (e) {
console.log(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]
})
}
console.log(this.data)
},
對(dui)于事件處理(li),聯動(dong)的(de)(de)(de)處理(li)邏(luo)輯,需要解釋的(de)(de)(de)我(wo)已在代碼實(shi)現中做(zuo)了解釋,也(ye)沒有什么比較(jiao)難以理(li)解的(de)(de)(de)內容,就不在過(guo)多(duo)介紹(shao),到這里微信小程序省市(shi)縣三級聯動(dong)效(xiao)果(guo)已經(jing)實(shi)現了。如(ru)果(guo)閱讀本文的(de)(de)(de)你發現文中有不妥或者(zhe)錯誤的(de)(de)(de)地方(fang),歡迎指正(zheng),在此謝(xie)過(guo)。Hava a wonderful day。