您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關微信小程序怎么實現省市區三級地址選擇,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
國際慣例先上效果圖:
省市區三級聯動,選擇省自動刷新市,選擇市自動刷新區,點擊取消自動返回上一級重新選擇,點擊確定,保存地址。
數據庫
這份數據庫是某天在網上逛到的,當時未記錄出處,直接貼出給讀者使用,實在不妥,此處僅貼出表結構,方便大家交流學習。如有讀者了解此份數據出處,煩請留言,謝謝!
數據表結構如下:
部分使用到的字段信息:
id:唯一標識每一個數據
name:地區名
parent_id:上級地區的id,若parent_id = 0 ,表示無上級信息,當前即為最高行政區。
extra:主要標識少數民族自治州或者自治縣的信息,如:巴音郭楞 蒙古 自治州,此處存儲 蒙古
例:
suffix:行政級別 市 省 縣 區等
部分地區數據信息如下:
后臺
后臺僅需提供一個接口,根據parent_id,查詢地區信息
此處使用的后臺是SSM框架,貼出主要接口、sql
1.與小程序交互接口
@RequestMapping(value = "/getArea", method = RequestMethod.POST) private @ResponseBody List<District> getArea(HttpServletRequest request) { int parentId = Integer.parseInt(request.getParameter("parentId")); logger.info("getArea"); List<District> list = new ArrayList<District>(); try { list = districtService.getAreas(parentId); } catch (Exception e) { } return list; }
2.查詢sql
<select id="getAreas" resultType="District"> <!-- 具體的sql --> SELECT id,concat(name,extra,suffix) as name,parent_id as parentId FROM district WHERE parent_id = #{parentId} </select>
前端
先貼出css:
.hotCity { padding-right: 50rpx; margin: auto; } .weui-grid { padding: 10rpx 0; width: 160rpx; box-sizing: border-box; border: 1rpx solid #ececec; border-radius: 8rpx; background-color: white; margin: 8rpx 0; } .weui-grids { display: flex; flex-direction: row; justify-content: space-between; } .weui-grid__label { display: block; text-align: center; color: #333; font-size: 30rpx; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; } .county { display: flex; flex-wrap: wrap; margin-top: 30px; margin-left: 15px; } /** 頭部css **/ .headTitle{ display: flex; } .headButton{ background: #f68135; border-radius: 25rpx; border: 1px solid #f68135; color: #fff; height: 80rpx; line-height: 80rpx; margin: 0 auto; width: 150rpx; font-size: 45rpx; text-align: center; padding:0px; vertical-align:middle ; }
html
html僅由兩部分組成:
頭部:確定、取消按鈕,顯示當前選擇地址信息
確定取消主要綁定了兩個方法:submitChoose 及 cancleChoose 兩個方法,點擊不同按鈕,執行不同js方法。
顯示當前地址信息:finalCity,只要在js中使用setData設置該值,該值就會動態改變。
city:顯示當前可選的地區
使用block組件,對json數組areaList進行循環顯示,同樣,使用setData設置該值,該值就會動態改變,達到省市區聯動選擇的效果。每一個小地區控件,有bindArea方法,并且在用戶選擇該地區,執行bindArea方法時,使用data-數據名的方法,向后臺傳遞用戶選擇數據。
<view class="headTitle"> <button class="headButton" bindtap="cancleChoose">取消</button> <view>{{finalCity == "" ? "請選擇地址" : finalCity}}</view> <button class="headButton" bindtap="submitChoose">確定</button> </view> <view class="county"> <block class="hotCity" wx:for-items="{{areaList}}" wx:key="id"> <view class="weui-grid" data-parentId="{{item.parentId}}" data-id="{{item.id}}" data-city="{{item.name}}" bindtap="bindArea"> <view class="weui-grid__label">{{item.name}}</view> </view> </block> </view>
js:
// pages/chooseCity/chooseCity.js //獲取應用實例 const model = require('../cityChoose/cityChoose.js') const config = require('../../utils/config.js') const util = require('../../utils/util.js') const app = getApp(); //記錄省市區 var nav = 0; var chooseCity = new Array(3); //記錄每一次的parentId var finalParentId = new Array(3); var flag = 0; Page({ /** * 頁面的初始數據 */ data: { finalCity:"", }, /** * 生命周期函數--監聽頁面加載 */ onLoad: function(options) { //parentId = 0 取所有省份數據 var that = this; that.getData(0); chooseCity = new Array("","",""); finalParentId = new Array(0,0,0); nav = 0; }, submitChoose:function(e){ if(flag != 1){ util.showLog("請選擇完整地址") return; }else{ var address_components = { "province": "", "city": "", "district": ""}; address_components["province"] = chooseCity[0]; address_components["city"] = chooseCity[1]; address_components["district"] = chooseCity[2]; console.log(address_components); app.globalData.address_components = address_components; wx.navigateBack(); } }, cancleChoose:function(e){ console.log(finalParentId); var that = this; if(nav == 0){ wx.navigateBack(); } else { nav = nav - 1; chooseCity[nav] = ""; console.log(chooseCity); that.setData({ finalCity: chooseCity[0] + chooseCity[1] + chooseCity[2] }) that.getData(finalParentId[nav]); } }, bindArea: function(e) { if(flag == 0){ console.log(e); var that = this; var parentId = e.currentTarget.dataset.id; var city = e.currentTarget.dataset.city; that.getData(parentId); chooseCity[nav] = city; finalParentId[nav] = e.currentTarget.dataset.parentid; nav++; console.log(chooseCity) that.setData({ finalCity:chooseCity[0]+chooseCity[1]+chooseCity[2] }) } }, getData(parentId) { var that = this; var url = config.getArea + "?parentId=" + parentId; wx.request({ url: url, success: (res) => { console.log("地區數據請求成功"); console.log(res) if (res.data.length != 0) { flag = 0; //設置數據到全局變量 that.setData({ areaList: res.data, }); }else{ //防止用戶再次點擊; flag = 1; } }, method: "POST", header: { "content-type": "application/x-www-form-urlencoded;charset=utf-8", }, fail: (res) => { console.log("地區數據請求失敗"); } }) }, })
js解析
全局變量作用:
//記錄用戶已選擇層次
var nav = 0;
//記錄省市區三級數據
var chooseCity = new Array(3);
//記錄每一次的parentId,主要記錄用戶選擇路徑,取消時根據用戶路徑顯示上一級數據
var finalParentId = new Array(3);
//記錄是否已經到最底層,再無數據可以選擇
var flag = 0;
執行過程:
進入頁面執行onLoad生命周期函數,在onLoad中調用getData初始化數據,及默認顯示行政級別為省的數據,即請求parent_id為0的數據
getData:
getData(parentId) { var that = this; //請求的url,由后臺決定,此處填入你的請求url即可 var url = config.getArea + "?parentId=" + parentId; wx.request({ url: url, success: (res) => { console.log("地區數據請求成功"); console.log(res) if (res.data.length != 0) { flag = 0; //設置數據到全局變量 that.setData({ areaList: res.data, }); }else{ //已到最后一層數據 flag = 1; } }, method: "POST", header: { "content-type": "application/x-www-form-urlencoded;charset=utf-8", }, fail: (res) => { console.log("地區數據請求失敗"); } }) },
點擊地區數據執行bindArea
bindArea: function(e) { //如果未到最后一層,即可向下執行 if(flag == 0){ console.log(e); var that = this; //獲取html傳參,獲取用戶點擊信息 var parentId = e.currentTarget.dataset.id; var city = e.currentTarget.dataset.city; //根據用戶點擊的數據,傳入當前的id作為下一層的parentId,請求下一層數據, that.getData(parentId); //記錄用戶選擇 chooseCity[nav] = city; //用戶點擊取消,到此層時,需要使用當前的parientid來請求此層應顯示的數據 finalParentId[nav] = e.currentTarget.dataset.parentid; //記錄路徑數+1 nav++; console.log(chooseCity) //更新用戶選擇地區顯示 that.setData({ finalCity:chooseCity[0]+chooseCity[1]+chooseCity[2] }) } },
點擊取消,執行方法cancleChoose
cancleChoose:function(e){ var that = this; //已是最后一層,則返回上一頁 if(nav == 0){ wx.navigateBack(); } else { //記錄路徑數-1 nav = nav - 1; //將上次已選擇的地區清空 chooseCity[nav] = ""; console.log(chooseCity); //更新選擇數據 that.setData({ finalCity: chooseCity[0] + chooseCity[1] + chooseCity[2] }) //根據finalParent中記錄的每一層應請求的數據來更新地區數據 that.getData(finalParentId[nav]); } },
點擊確定,執行方法submitChoose
submitChoose:function(e){ //如果未到最后一層,表示地址未選擇完,如果不需要選擇完整地址,此處去掉即可 if(flag != 1){ util.showLog("請選擇完整地址") return; }else{ //存儲數據到全局變量中,采用了json的方式存儲,可以分別存儲省市區數據 var address_components = { "province": "", "city": "", "district": ""}; address_components["province"] = chooseCity[0]; address_components["city"] = chooseCity[1]; address_components["district"] = chooseCity[2]; console.log(address_components); app.globalData.address_components = address_components; //返回上一次頁面 wx.navigateBack(); } },
謝謝大家查看,評論里希望貼出cityChoose.js 及 util.js ,在下面貼出來啦,注:util.js里不是所有方法都要用到。
希望能夠幫助到大家。
cityChoose
// pages/chooseCity/chooseCity.js //獲取應用實例 const model = require('../cityChoose/cityChoose.js') const config = require('../../utils/config.js') const util = require('../../utils/util.js') const app = getApp(); //記錄省市區 var nav = 0; var chooseCity = new Array(3); //記錄每一次的parentId var finalParentId = new Array(3); //記錄是否到最后一級 var flag = 0; Page({ /** * 頁面的初始數據 */ data: { finalCity:"", }, /** * 生命周期函數--監聽頁面加載 */ onLoad: function(options) { //parentId = 0 取所有省份數據 var that = this; that.getData(0); chooseCity = new Array("","",""); finalParentId = new Array(0,0,0); nav = 0; }, submitChoose:function(e){ if(flag != 1){ util.showLog("請選擇完整地址") return; }else{ var address_components = { "province": "", "city": "", "district": ""}; address_components["province"] = chooseCity[0]; address_components["city"] = chooseCity[1]; address_components["district"] = chooseCity[2]; console.log(address_components); app.globalData.address_components = address_components; wx.navigateBack(); } }, cancleChoose:function(e){ console.log(finalParentId); var that = this; if(nav == 0){ wx.navigateBack(); } else { nav = nav - 1; chooseCity[nav] = ""; console.log(chooseCity); that.setData({ finalCity: chooseCity[0] + chooseCity[1] + chooseCity[2] }) that.getData(finalParentId[nav]); } }, bindArea: function(e) { if(flag == 0){ console.log(e); var that = this; var parentId = e.currentTarget.dataset.id; var city = e.currentTarget.dataset.city; //刷新出下一級地址前重復點擊 console.log(chooseCity[nav - 1] ); console.log(city); if(chooseCity[nav-1] == city){ return; } that.getData(parentId); chooseCity[nav] = city; finalParentId[nav] = e.currentTarget.dataset.parentid; nav++; console.log(chooseCity) that.setData({ finalCity:chooseCity[0]+chooseCity[1]+chooseCity[2] }) } }, getData(parentId) { var that = this; var url = config.getArea + "?parentId=" + parentId; wx.request({ url: url, success: (res) => { console.log("地區數據請求成功"); console.log(res) if (res.data.length != 0) { flag = 0; //設置數據到全局變量 that.setData({ areaList: res.data, }); }else{ //防止用戶再次點擊; flag = 1; } }, method: "POST", header: { "content-type": "application/x-www-form-urlencoded;charset=utf-8", }, fail: (res) => { console.log("地區數據請求失敗"); } }) }, })
util.js
const formatTime = date => { const year = date.getFullYear() const month = date.getMonth() + 1 const day = date.getDate() const hour = date.getHours() const minute = date.getMinutes() const second = date.getSeconds() return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') } const formatNumber = n => { n = n.toString() return n[1] ? n : '0' + n } function showLog(e) { wx.showToast({ title: e, icon: "none" }) } function trim(str) { return str.replace(/(^\s*)|(\s*$)/g, ""); } function showLoading() { wx.showLoading({ title: '加載中', mask: true }) } // 驗證碼倒計時 function phone_code(t, second) { // t是this,second是重新發送的間隔時間,需要設置按鈕可點擊 var s = second; // 避免重復點擊 t.setData({ phone_code_text: s + "s", phone_code_class: "", phone_code_buff: true }); // 倒計時 var clock = setInterval(function () { if (s > 1) { t.setData({ phone_code_text: --s + "s" }) } else { clearInterval(clock); t.setData({ phone_code_text: "重新發送", phone_code_class: "on", phone_code_buff: false }); // 重置數據 s = second; } }, 1000) } function getNowFormatDate() { var date = new Date(); var seperator1 = "-"; var year = date.getFullYear(); var month = date.getMonth() + 1; var strDate = date.getDate(); if (month >= 1 && month <= 9) { month = "0" + month; } if (strDate >= 0 && strDate <= 9) { strDate = "0" + strDate; } var currentdate = year + seperator1 + month + seperator1 + strDate; return currentdate; } function checkAndCall(sourceId,recordType,tele,app,config){ console.log(app.globalData.haulUserInfo) console.log(tele); if (app.globalData.haulUserInfo == null) { showLog("正在獲取用戶數據,請稍后。") app.Promise.then(function (value) { console.log(value); if (value) { // success wx.makePhoneCall({ phoneNumber: tele, success: ph => { mycall(config, app,recordType, sourceId, function () { //記錄聯系次數 }) } }) } else { // failure showLog("注冊完成即可聯系" + "。。。即將跳轉") setTimeout(function () { wx.navigateTo({ url: '../registUser/registUser', }) }, 1000); } }).catch(function (error) { }); } else { // success wx.makePhoneCall({ phoneNumber: tele, success: ph => { mycall(config,app, recordType, sourceId,function () { //記錄聯系次數 }) } }) } } //記錄互相聯系 function mycall(config,app, recordType, sourceId, callback) { console.log(typeof (recordType)) var that = this; wx.request({ url: config.insertRecord, method: "POST", data: { sourceId: sourceId, userId: app.globalData.haulUserInfo.id, recordType: recordType }, header: { "content-type": "application/x-www-form-urlencoded", }, success: res => { if (res.data.success) { console.log('聯系成功'); callback(); } else { showLog(res.data.error); } } }) } module.exports = { formatNumber: formatNumber, formatTime: formatTime, phone_code_clock: phone_code, showLoading: showLoading, showLog: showLog, getNowFormatDate: getNowFormatDate, trim: trim, mycall: mycall, checkAndCall: checkAndCall }
關于微信小程序怎么實現省市區三級地址選擇就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。