溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

微信小程序怎么實(shí)現(xiàn)省市區(qū)三級(jí)地址選擇

發(fā)布時(shí)間:2020-06-23 09:36:53 來源:億速云 閱讀:478 作者:清晨 欄目:web開發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)微信小程序怎么實(shí)現(xiàn)省市區(qū)三級(jí)地址選擇,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

國際慣例先上效果圖:

省市區(qū)三級(jí)聯(lián)動(dòng),選擇省自動(dòng)刷新市,選擇市自動(dòng)刷新區(qū),點(diǎn)擊取消自動(dòng)返回上一級(jí)重新選擇,點(diǎn)擊確定,保存地址。

微信小程序怎么實(shí)現(xiàn)省市區(qū)三級(jí)地址選擇微信小程序怎么實(shí)現(xiàn)省市區(qū)三級(jí)地址選擇微信小程序怎么實(shí)現(xiàn)省市區(qū)三級(jí)地址選擇

數(shù)據(jù)庫

這份數(shù)據(jù)庫是某天在網(wǎng)上逛到的,當(dāng)時(shí)未記錄出處,直接貼出給讀者使用,實(shí)在不妥,此處僅貼出表結(jié)構(gòu),方便大家交流學(xué)習(xí)。如有讀者了解此份數(shù)據(jù)出處,煩請(qǐng)留言,謝謝!

數(shù)據(jù)表結(jié)構(gòu)如下:

微信小程序怎么實(shí)現(xiàn)省市區(qū)三級(jí)地址選擇

部分使用到的字段信息:

id:唯一標(biāo)識(shí)每一個(gè)數(shù)據(jù)

name:地區(qū)名

parent_id:上級(jí)地區(qū)的id,若parent_id = 0 ,表示無上級(jí)信息,當(dāng)前即為最高行政區(qū)。

extra:主要標(biāo)識(shí)少數(shù)民族自治州或者自治縣的信息,如:巴音郭楞 蒙古 自治州,此處存儲(chǔ) 蒙古 

例:

微信小程序怎么實(shí)現(xiàn)省市區(qū)三級(jí)地址選擇

suffix:行政級(jí)別 市 省 縣 區(qū)等

部分地區(qū)數(shù)據(jù)信息如下:

微信小程序怎么實(shí)現(xiàn)省市區(qū)三級(jí)地址選擇

后臺(tái)

后臺(tái)僅需提供一個(gè)接口,根據(jù)parent_id,查詢地區(qū)信息

此處使用的后臺(tái)是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僅由兩部分組成:

頭部:確定、取消按鈕,顯示當(dāng)前選擇地址信息

         確定取消主要綁定了兩個(gè)方法:submitChoose 及 cancleChoose 兩個(gè)方法,點(diǎn)擊不同按鈕,執(zhí)行不同js方法。

         顯示當(dāng)前地址信息:finalCity,只要在js中使用setData設(shè)置該值,該值就會(huì)動(dòng)態(tài)改變。

city:顯示當(dāng)前可選的地區(qū)

        使用block組件,對(duì)json數(shù)組areaList進(jìn)行循環(huán)顯示,同樣,使用setData設(shè)置該值,該值就會(huì)動(dòng)態(tài)改變,達(dá)到省市區(qū)聯(lián)動(dòng)選擇的效果。每一個(gè)小地區(qū)控件,有bindArea方法,并且在用戶選擇該地區(qū),執(zhí)行bindArea方法時(shí),使用data-數(shù)據(jù)名的方法,向后臺(tái)傳遞用戶選擇數(shù)據(jù)。

<view class="headTitle">
<button class="headButton" bindtap="cancleChoose">取消</button>
<view>{{finalCity == "" &#63; "請(qǐng)選擇地址" : 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
//獲取應(yīng)用實(shí)例
const model = require('../cityChoose/cityChoose.js')
const config = require('../../utils/config.js')
const util = require('../../utils/util.js')
const app = getApp();
//記錄省市區(qū)
var nav = 0;
var chooseCity = new Array(3);
//記錄每一次的parentId
var finalParentId = new Array(3);
var flag = 0;
Page({
 
 /**
 * 頁面的初始數(shù)據(jù)
 */
 data: {
 finalCity:"",
 },
 
 /**
 * 生命周期函數(shù)--監(jiān)聽頁面加載
 */
 onLoad: function(options) {
 //parentId = 0 取所有省份數(shù)據(jù)
 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("請(qǐng)選擇完整地址")
 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 + "&#63;parentId=" + parentId;
 wx.request({
 url: url,
 success: (res) => {
 console.log("地區(qū)數(shù)據(jù)請(qǐng)求成功");
 console.log(res)
 if (res.data.length != 0) {
  flag = 0;
  //設(shè)置數(shù)據(jù)到全局變量
  that.setData({
  areaList: res.data,
  });
 }else{
  //防止用戶再次點(diǎn)擊;
  flag = 1;
 }
 },
 method: "POST",
 header: {
 "content-type": "application/x-www-form-urlencoded;charset=utf-8",
 },
 fail: (res) => {
 console.log("地區(qū)數(shù)據(jù)請(qǐng)求失敗");
 }
 })
 },
})

js解析

全局變量作用:

      //記錄用戶已選擇層次

      var nav = 0;

      //記錄省市區(qū)三級(jí)數(shù)據(jù)

       var chooseCity = new Array(3);

      //記錄每一次的parentId,主要記錄用戶選擇路徑,取消時(shí)根據(jù)用戶路徑顯示上一級(jí)數(shù)據(jù)

     var finalParentId = new Array(3);

    //記錄是否已經(jīng)到最底層,再無數(shù)據(jù)可以選擇

    var flag = 0;

執(zhí)行過程:

    進(jìn)入頁面執(zhí)行onLoad生命周期函數(shù),在onLoad中調(diào)用getData初始化數(shù)據(jù),及默認(rèn)顯示行政級(jí)別為省的數(shù)據(jù),即請(qǐng)求parent_id為0的數(shù)據(jù)

  getData: 

getData(parentId) {
 var that = this;
//請(qǐng)求的url,由后臺(tái)決定,此處填入你的請(qǐng)求url即可
 var url = config.getArea + "&#63;parentId=" + parentId;
 wx.request({
 url: url,
 success: (res) => {
 console.log("地區(qū)數(shù)據(jù)請(qǐng)求成功");
 console.log(res)
 if (res.data.length != 0) {
  flag = 0;
  //設(shè)置數(shù)據(jù)到全局變量
  that.setData({
  areaList: res.data,
  });
 }else{
  //已到最后一層數(shù)據(jù)
  flag = 1;
 }
 },
 method: "POST",
 header: {
 "content-type": "application/x-www-form-urlencoded;charset=utf-8",
 },
 fail: (res) => {
 console.log("地區(qū)數(shù)據(jù)請(qǐng)求失敗");
 }
 })
 },

點(diǎn)擊地區(qū)數(shù)據(jù)執(zhí)行bindArea

bindArea: function(e) {
 //如果未到最后一層,即可向下執(zhí)行 
 if(flag == 0){
 console.log(e);
 var that = this;
 //獲取html傳參,獲取用戶點(diǎn)擊信息
 var parentId = e.currentTarget.dataset.id;
 var city = e.currentTarget.dataset.city;
 //根據(jù)用戶點(diǎn)擊的數(shù)據(jù),傳入當(dāng)前的id作為下一層的parentId,請(qǐng)求下一層數(shù)據(jù),
 that.getData(parentId);
 //記錄用戶選擇
 chooseCity[nav] = city;
//用戶點(diǎn)擊取消,到此層時(shí),需要使用當(dāng)前的parientid來請(qǐng)求此層應(yīng)顯示的數(shù)據(jù)
 finalParentId[nav] = e.currentTarget.dataset.parentid;
//記錄路徑數(shù)+1
 nav++;
 console.log(chooseCity)
//更新用戶選擇地區(qū)顯示
 that.setData({
 finalCity:chooseCity[0]+chooseCity[1]+chooseCity[2]
 })
 }
 },

點(diǎn)擊取消,執(zhí)行方法cancleChoose

cancleChoose:function(e){
 var that = this;
//已是最后一層,則返回上一頁
 if(nav == 0){
 wx.navigateBack();
 } else {
//記錄路徑數(shù)-1
 nav = nav - 1;
//將上次已選擇的地區(qū)清空
 chooseCity[nav] = "";
 console.log(chooseCity);
//更新選擇數(shù)據(jù)
 that.setData({
 finalCity: chooseCity[0] + chooseCity[1] + chooseCity[2]
 })
//根據(jù)finalParent中記錄的每一層應(yīng)請(qǐng)求的數(shù)據(jù)來更新地區(qū)數(shù)據(jù)
 that.getData(finalParentId[nav]);
 }
 },

點(diǎn)擊確定,執(zhí)行方法submitChoose   

submitChoose:function(e){
//如果未到最后一層,表示地址未選擇完,如果不需要選擇完整地址,此處去掉即可
 if(flag != 1){
 util.showLog("請(qǐng)選擇完整地址")
 return;
 }else{
//存儲(chǔ)數(shù)據(jù)到全局變量中,采用了json的方式存儲(chǔ),可以分別存儲(chǔ)省市區(qū)數(shù)據(jù)
 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();
 }
 },

謝謝大家查看,評(píng)論里希望貼出cityChoose.js 及 util.js ,在下面貼出來啦,注:util.js里不是所有方法都要用到。

希望能夠幫助到大家。

cityChoose

// pages/chooseCity/chooseCity.js
//獲取應(yīng)用實(shí)例
const model = require('../cityChoose/cityChoose.js')
const config = require('../../utils/config.js')
const util = require('../../utils/util.js')
const app = getApp();
//記錄省市區(qū)
var nav = 0;
var chooseCity = new Array(3);
//記錄每一次的parentId
var finalParentId = new Array(3);
//記錄是否到最后一級(jí)
var flag = 0;
Page({
 
 /**
 * 頁面的初始數(shù)據(jù)
 */
 data: {
 finalCity:"",
 },
 
 /**
 * 生命周期函數(shù)--監(jiān)聽頁面加載
 */
 onLoad: function(options) {
 //parentId = 0 取所有省份數(shù)據(jù)
 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("請(qǐng)選擇完整地址")
 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;
 //刷新出下一級(jí)地址前重復(fù)點(diǎn)擊
 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 + "&#63;parentId=" + parentId;
 wx.request({
 url: url,
 success: (res) => {
 console.log("地區(qū)數(shù)據(jù)請(qǐng)求成功");
 console.log(res)
 if (res.data.length != 0) {
  flag = 0;
  //設(shè)置數(shù)據(jù)到全局變量
  that.setData({
  areaList: res.data,
  });
 }else{
  //防止用戶再次點(diǎn)擊;
  flag = 1;
 }
 },
 method: "POST",
 header: {
 "content-type": "application/x-www-form-urlencoded;charset=utf-8",
 },
 fail: (res) => {
 console.log("地區(qū)數(shù)據(jù)請(qǐng)求失敗");
 }
 })
 },
})

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] &#63; 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
 })
}
 
// 驗(yàn)證碼倒計(jì)時(shí)
function phone_code(t, second) {
 // t是this,second是重新發(fā)送的間隔時(shí)間,需要設(shè)置按鈕可點(diǎn)擊
 var s = second;
 // 避免重復(fù)點(diǎn)擊
 t.setData({
 phone_code_text: s + "s",
 phone_code_class: "",
 phone_code_buff: true
 });
 
 // 倒計(jì)時(shí)
 var clock = setInterval(function () {
 if (s > 1) {
 t.setData({
 phone_code_text: --s + "s"
 })
 } else {
 clearInterval(clock);
 t.setData({
 phone_code_text: "重新發(fā)送",
 phone_code_class: "on",
 phone_code_buff: false
 });
 // 重置數(shù)據(jù)
 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("正在獲取用戶數(shù)據(jù),請(qǐng)稍后。")
 app.Promise.then(function (value) {
 console.log(value);
 if (value) {
 // success
 wx.makePhoneCall({
  phoneNumber: tele,
  success: ph => {
  mycall(config, app,recordType, sourceId, function () {
  //記錄聯(lián)系次數(shù)
  })
  }
 })
 } else {
 // failure
 showLog("注冊完成即可聯(lián)系" + "。。。即將跳轉(zhuǎn)")
 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 () {
  //記錄聯(lián)系次數(shù)
 
 })
 }
 })
 }
}
 
//記錄互相聯(lián)系
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('聯(lián)系成功');
 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
}

關(guān)于微信小程序怎么實(shí)現(xiàn)省市區(qū)三級(jí)地址選擇就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI