国际惯例先上效果图:
省市区三级联动,选择省自动刷新市,选择市自动刷新区,点击取消自动返回上一级重新选择,点击确定,保存地址。
数据库
这份数据库是某天在网上逛到的,当时未记录出处,直接贴出给读者使用,实在不妥,此处仅贴出表结构,方便大家交流学习。如有读者了解此份数据出处,烦请留言,谢谢!
数据表结构如下:
部分使用到的字段信息:
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 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> <button bindtap="cancleChoose">取消</button> <view>{{finalCity == "" ? "请选择地址" : finalCity}}</view> <button bindtap="submitChoose">确定</button> </view> <view> <block wx:for-items="{{areaList}}" wx:key="id"> <view data-parentId="{{item.parentId}}" data-id="{{item.id}}" data-city="{{item.name}}" bindtap="bindArea"> <view>{{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: