【愚公系列】2022年08月 微信小程序-省市区三联动功能实现
生活随笔
收集整理的這篇文章主要介紹了
【愚公系列】2022年08月 微信小程序-省市区三联动功能实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
文章目錄
- 前言
- 一、picker選擇器
- 二、js滾動選擇器實現
- 1.組件封裝
- 2.使用
- 3.效果
- 三、wxs滾動選擇器實現
- 1.組件封裝
- 2.使用
- 3.效果
- 四、相關組件pop-up四件套
前言
多級聯動下拉菜單是前端常見的效果,省市區三級聯動又屬于其中最典型的案例。多級聯動一般都是與數據相關聯的,根據數據來生成和修改聯動的下拉菜單。完成一個多級聯動效果,有助于增強對數據處理的能力。
數據可以是后臺從數據庫讀出來的數據,也可以是在JS里直接寫的數據。但無論是哪種形式,三個數組的數據都是有關聯的。
citys,市數組,里面每一項內容都有一個屬性表示這個市是屬于哪個省的,即對應的是省數組里的id。
同樣areas,區數組,里面都有屬性是對應市數組里的id,表示這個區是屬于哪個市的。
相關json數據鏈接:https://download.csdn.net/download/aa2528877987/86504988
小程序是自帶省市區選擇器的,下面介紹三種方式實現省市區三聯動
一、picker選擇器
在小程序mode = region就代表是省市區選擇器,不過這種選擇器比較局限,無法自定義。
<view class="section"><view class="section__title">省市區選擇器</view><picker mode="region" bindchange="bindRegionChange" value="{{region}}" custom-item="{{customItem}}"><view class="picker">當前選擇:{{region[0]}},{{region[1]}},{{region[2]}}</view></picker> </view> Page({data: {region: ['廣東省', '廣州市', '海珠區'],customItem: '全部'},bindRegionChange: function (e) {console.log('picker發送選擇改變,攜帶值為', e.detail.value)this.setData({region: e.detail.value})} })二、js滾動選擇器實現
1.組件封裝
city.js相關json數據鏈接:https://download.csdn.net/download/aa2528877987/86504988
組件index四件套
// 該組件參照了以下文章,感興趣請前往查看原文 // https://developers.weixin.qq.com/community/develop/article/doc/0000643f674fa81a18a92b37455413 // 在此對原作者表示感謝~var app = getApp() var address = require('./city.js')// components/region-picker-view/index.js Component({options: {multipleSlots: false // 在組件定義時的選項中啟用多slot支持},/*** 組件的屬性列表*/properties: {},/*** 組件的初始數據*/data: {address: '', //詳細收貨地址(四級)value: [0, 0, 0], // 地址選擇器省市區 暫存 currentIndexregion: '', //所在地區regionValue: [0, 0, 0], // 地址選擇器省市區 最終 currentIndexprovinces: [], // 一級地址citys: [], // 二級地址areas: [], // 三級地址visible: false},ready(){// 默認聯動顯示北京var id = address.provinces[0].id this.setData({provinces: address.provinces, // 34省citys: address.citys[id], //默認北京市轄區areas: address.areas[address.citys[id][0].id]})},/*** 組件的方法列表*/methods: {closePopUp() {this.setData({visible: false})},pickAddress() {this.setData({visible: true,value: [...this.data.regionValue]})},// 處理省市縣聯動邏輯 并保存 value cityChange(e) {var value = e.detail.valuelet {provinces,citys} = this.datavar provinceNum = value[0]var cityNum = value[1]var areaNum = value[2]if (this.data.value[0] !== provinceNum) {var id = provinces[provinceNum].idthis.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].idthis.setData({value: [provinceNum, cityNum, 0],areas: address.areas[citys[cityNum].id]})} else {this.setData({value: [provinceNum, cityNum, areaNum]})} },preventTouchmove() {},// 城市選擇器// 點擊地區選擇取消按鈕cityCancel(e) {var id = address.provinces[0].id this.setData({citys: this.data.lastCitys || address.citys[id], //默認北京市轄區,areas: this.data.lastAreas || address.areas[address.citys[id][0].id],value: [...this.data.regionValue],visible: false})},// 提交時由序號獲取省市區idgetRegionId(type) {let value = this.data.regionValuelet provinceId = address.provinces[value[0]].idlet townId = address.citys[provinceId][value[1]].idlet areaId = ''if (address.areas[townId][value[2]].id) {areaId = address.areas[townId][value[2]].id} else {areaId = 0}if (type === 'provinceId') {return provinceId} else if (type === 'townId') {return townId} else {return areaId}},// 點擊地區選擇確定按鈕citySure(e) {var value = this.data.valuethis.setData({visible: false})// 將選擇的城市信息顯示到輸入框try {var region = (this.data.provinces[value[0]].name || '') + (this.data.citys[value[1]].name || '')if (this.data.areas.length > 0) {region = region + this.data.areas[value[2]].name || ''} else {this.data.value[2] = 0}} catch (error) {console.log('adress select something error')}this.setData({region: region,lastCitys: this.data.citys,lastAreas: this.data.areas,regionValue: [...this.data.value]}, () => {console.log(`省份ID:${this.getRegionId('provinceId')}: 市區ID:${this.getRegionId('townId')}:城區ID:${this.getRegionId('areas')}`)this.triggerEvent('change',{value:{region,province:{id:this.getRegionId('provinceId'),name:this.data.provinces[value[0]].name},town:{id:this.getRegionId('townId'),name:this.data.citys[value[1]].name},area:{id:this.getRegionId('areas'),name:this.data.areas[value[2]].name}}})})}} }) {"component": true,"usingComponents": {"pop-up": "../pop-up/index"} } <!--components/region-picker-view/index.wxml--> <view class="address-item" bindtap="pickAddress"><view class="item-title">所在地區:</view><view class="item-content arrow {{region ? '' : 'item-content_shadow' }}">{{region||"請選擇"}}</view> </view> <pop-up visible="{{visible}}" onClose="closePopUp"><view slot="content"><view class="picker-view"><view class="picker-view__pane"><text catchtap="cityCancel">取消</text><text catchtap="citySure">確定</text></view> <picker-view class="pick-view__group" bindchange="cityChange" value="{{value}}" wx:key="*this"><picker-view-column indicator-class="item_active"><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></view> </pop-up> /* components/region-picker-view/index.wxss */ .address-item {min-height: 98rpx;display: flex;justify-content: flex-start;align-items: center;border-bottom: 1px solid #f1f1f1;padding: 0 32rpx }.item-title {width: 140rpx;color: #4d4c4c;font-size: 28rpx;height: 98rpx;line-height: 98rpx; } .item-content {width: 520rpx;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;font-size: 28rpx;height: 98rpx;line-height: 98rpx;color: #4d4c4c; } /* 地區級聯選擇器 */.picker-view {width: 100%;display: flex;background-color: #fff;flex-direction: column;justify-content: center;align-items: center;bottom: 0rpx;left: 0rpx; }.picker-item {line-height: 70rpx;margin-left: 5rpx;margin-right: 5rpx;text-align: center; }.picker-view__pane {height: 100rpx;width: 100%;padding: 20rpx 32rpx;display: flex;justify-content: space-between;align-items: center;box-sizing: border-box; }.picker-view__pane text{color: #00cc88;font-size: 30rpx; }.pick-view__group {width: 96%;height: 450rpx; }2.使用
<region-picker-view bindchange="onRegionChange"></region-picker-view> onRegionChange(e){console.log('選擇了',e.detail); },3.效果
三、wxs滾動選擇器實現
1.組件封裝
city.wxs相關json數據鏈接:https://download.csdn.net/download/aa2528877987/86504988
// 該組件參照了以下文章,感興趣請前往查看原文 // https://developers.weixin.qq.com/community/develop/article/doc/0000643f674fa81a18a92b37455413 // 在此對原作者表示感謝~// var address = require('./city') Component({options: {multipleSlots: false },properties: {},data: {// value: [0, 0, 0], // 地址選擇器省市區 暫存 currentIndex// regionText: '', //所在地區// provinces: null, // 一級地址// citys: null, // 二級地址// areas: null, // 三級地址visible: false},ready(){},methods: {} }) {"component": true,"usingComponents": {"pop-up": "../pop-up/index"} } <!--components/region-picker-view2/index.wxml--> <wxs module="region" src="./region.wxs"></wxs> <view change:class="{{region.onPropSigned}}" class="address-item" bindtap="{{region.pickAddress}}"><view class="item-title">所在地區:</view><view class="item-content arrow {{regionText ? '' : 'item-content_shadow' }}">{{regionText||"請選擇"}}</view> </view> <pop-up visible="{{visible}}" onClose="closePopUp" bindready="{{region.onComponentReady}}"><view slot="content"><view class="picker-view"><view class="picker-view__pane"><text catchtap="{{region.onCancel}}">取消</text><text catchtap="{{region.onSure}}">確定</text></view><picker-view class="pick-view__group" bindpickstart="{{region.onPickStart}}" bindpickend="{{region.onPickEnd}}" bindchange="{{region.onChange}}" value="{{value}}" wx:key="*this"> <picker-view-column indicator-class="item_active"><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></view> </pop-up> /* components/region-picker-view/index.wxss */ .address-item {min-height: 98rpx;display: flex;justify-content: flex-start;align-items: center;border-bottom: 1px solid #f1f1f1;padding: 0 32rpx }.item-title {width: 140rpx;color: #4d4c4c;font-size: 28rpx;height: 98rpx;line-height: 98rpx; } .item-content {width: 520rpx;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;font-size: 28rpx;height: 98rpx;line-height: 98rpx;color: #4d4c4c; } /* 地區級聯選擇器 */.picker-view {width: 100%;display: flex;background-color: #fff;flex-direction: column;justify-content: center;align-items: center;bottom: 0rpx;left: 0rpx; }.picker-item {line-height: 70rpx;margin-left: 5rpx;margin-right: 5rpx;text-align: center; }.picker-view__pane {height: 100rpx;width: 100%;padding: 20rpx 32rpx;display: flex;justify-content: space-between;align-items: center;box-sizing: border-box; }.picker-view__pane text{color: #00cc88;font-size: 30rpx; }.pick-view__group {width: 96%;height: 450rpx; } var address = require('./city.wxs') var region = {provinces: [], citys: [], areas: [], value: [-1, 0, 0] //選定的值,, selectedValue: [0, 0, 0]//當前選擇的值 } var dataIsDirty = false var defaultProvinceId = address.provinces[0].id region.provinces = address.provinces region.citys = address.citys[defaultProvinceId] //默認北京市轄區 region.areas = address.areas[address.citys[defaultProvinceId][0].id]// 選擇省與城市,觸發數據變動 function onSelectedValueChanged(ownerInstance) {var selectedValue = region.selectedValue, value = region.valuevar provinceNum = selectedValue[0]var cityNum = selectedValue[1]if (value[0] !== provinceNum) {var id = region.provinces[provinceNum].idregion.selectedValue = [provinceNum, 0, 0]region.citys = address.citys[id]region.areas = address.areas[address.citys[id][0].id]} else if (value[1] !== cityNum) {var id = region.citys[cityNum].idregion.selectedValue = [provinceNum, cityNum, 0]region.areas = address.areas[region.citys[cityNum].id]}ownerInstance.callMethod("setData", {citys: region.citys, areas: region.areas}) } function getRegionId(value, type) {var provinceId = address.provinces[value[0]].idvar townId = address.citys[provinceId][value[1]].idvar areaId = ''if (address.areas[townId][value[2]].id) {areaId = address.areas[townId][value[2]].id} else {areaId = 0}if (type === 'provinceId') {return provinceId} else if (type === 'townId') {return townId} else {return areaId} }region.onPickStart = function (e, owner) {console.log(e.type, e.detail) } region.onPickEnd = function (e, owner) {if (dataIsDirty) {onSelectedValueChanged(owner)dataIsDirty = false} } region.onChange = function (e, owner) {console.log(e.type, e.detail)if ('' + region.selectedValue != '' + e.detail.value) {dataIsDirty = trueregion.selectedValue = e.detail.value} } region.onCancel = function (e, owner) {// console.log(e.type, e.detail)var value = region.value var provinceId = address.provinces[value[0]].id owner.callMethod("setData",{citys:address.citys[provinceId],areas: address.areas[address.citys[provinceId][value[1]].id],visible:false }) } region.onSure = function (e, owner) {// console.log(e.type, e.detail)var value = region.value = region.selectedValuevar regionTextArr = ['','','']// 將選擇的城市信息顯示到輸入框regionTextArr[0] = region.provinces[value[0]].name || ''if (region.citys[value[1]]){regionTextArr[1] = region.citys[value[1]].name || ''} if (region.areas[value[2]]) {regionTextArr[2] = region.areas[value[2]].name || ''} else {value[2] = 0}var regionText = regionTextArr.join('')owner.callMethod("setData",{regionText:regionText,value:value ,visible:false })owner.triggerEvent("change", {value: {region: regionText,province: {id: getRegionId(region.value, 'provinceId'),name: regionTextArr[0]},town: {id: getRegionId(region.value, 'townId'),name: regionTextArr[1]},area: {id: getRegionId(region.value, 'areas'),name: regionTextArr[2]}}}) } region.pickAddress = function(e, owner) {owner.callMethod("setData",{visible: true}) }, // Cannot use wxs function to handle custom event "ready" region.onComponentReady = function (e, owner) {console.log(e, "onComponentReady");// onSelectedValueChanged(owner) } // ownerInstance不一定是頁面對象 region.onPropSigned = function(newValue, oldValue, ownerInstance, instance){console.log("onPropSigned",newValue, oldValue, ownerInstance, instance)ownerInstance.callMethod("setData", {provinces: region.provinces, citys: region.citys, areas: region.areas, value: [0, 0, 0] // 地址選擇器省市區 暫存 currentIndex, regionText: ''}) }module.exports = region2.使用
<region-picker-view bindchange="onRegionChange"></region-picker-view> onRegionChange(e){console.log('選擇了',e.detail); },3.效果
四、相關組件pop-up四件套
Component({options: {multipleSlots: true // 在組件定義時的選項中啟用多slot支持},/*** 組件的屬性列表*/properties: {visible: {type: Boolean,value: false}},/*** 組件的初始數據*/data: {},ready(){this.triggerEvent('ready')},/*** 組件的方法列表*/methods: {popPreventTouchmove() { },popPreventTouchmove2() { },popPreventTouchmove3() { },cityChange() { },close() {this.triggerEvent('close')},handleClickMask(e) {// console.log(e)if (e.target.dataset.type !== 'unclose') this.close()}} }) {"component": true,"usingComponents": {} } <view catchtouchmove="popPreventTouchmove"><view class="q-pp-mask {{ visible ? 'q-pp-mask-show' : '' }} ptp_exposure" bindtap="handleClickMask" catchtouchmove="popPreventTouchmove"><view class=" q-pp {{ visible ? 'q-pp-show' : '' }}" catchtouchmove="popPreventTouchmove"><slot name="content" data-type="unclose"></slot></view></view> </view> .q-pp {position: fixed;width: 100%;box-sizing: border-box;left: 0;right: 0;bottom: 0;background: #f7f7f7;transform: translate3d(0, 100%, 0);transform-origin: center;transition: all 0.2s ease-in-out;z-index: 900;visibility: hidden; }.q-pp-show {transform: translate3d(0, 0, 0);visibility: visible; }.q-pp-mask {position: fixed;top: 0;left: 0;right: 0;bottom: 0;background: rgba(0, 0, 0, 0.7);z-index: 900;transition: all 0.2s ease-in-out;opacity: 0;visibility: hidden; }.q-pp-mask-show {opacity: 1;visibility: visible; }總結
以上是生活随笔為你收集整理的【愚公系列】2022年08月 微信小程序-省市区三联动功能实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: STM32串口通信控制pwm
- 下一篇: 关系代数中的除法运算