之前的那篇百度小程序三级联动的博客自认为写得不够好,比较偏理论,基本在讲picker组件中的各个参数的意思;这篇是在上一篇的基础上对三级联动重写了一遍,实现的效果要比上一篇好,还支持用户点击编辑收获地址的时候input框内显示省市区地址。
上篇的三级联动的省市区数据都是通过发送请求获取的,本篇的三级联动的数据都是使用本地文件里面的数据,具体看下面代码。
// 导入验证js
const app = getApp();
import WxValidate from "../../utils/WxValidate";
import { axios } from "../../utils/request";
import region from "../../utils/region";
import {
setAddressList,
getAddressList,
setProvinceList,
getProvinceList
} from "../../utils/storage";
import { showToast } from "../../utils/index";
Page({
data: {
multiIndex: [0, 0, 0], // 默认的下标 [省、市、区]
step: 0, // 默认显示请选择
// 设置默认收货地址按钮选中状态
value: ""
},
onLoad() {
// console.log("openid: ", app.globalData.openid);
// 初始化表单验证规则
this.initValidate();
// 获取省的数据
this.getProvince();
},
// 提交表单
formSubmit(e) {
if (this.data.step == 0) {
swan.showToast({
title: "请选择收货城市",
icon: "none",
duration: 4000,
mask: false
});
return;
}
let params = e.detail.value;
// console.log(params);
// 省的名字
let DeliveryName = this.data.provinceList[params["receivingAddress"][0]]
.name;
// 市的名字
let CityName = this.data.cityList[params["receivingAddress"][1]].name;
// 区的名字
let storeName = this.data.storeList[params["receivingAddress"][2]].name;
// 如果市和区名称相同就只市的名称
let DeliveryAddress;
(CityName == storeName) ? DeliveryAddress = DeliveryName + CityName : DeliveryAddress = DeliveryName + CityName + storeName;
// console.log("DeliveryAddress是不是undefined", DeliveryAddress + params.CustomArea);
// console.log("DeliveryAddress是不是undefined", DeliveryAddress + params.CustomArea);
let storeNumber = params["receivingAddress"][2];
let storeCode = this.data.storeList[storeNumber].code;
if (!this.WxValidate.checkForm(params)) {
//表单元素验证不通过,此处给出相应提示
let error = this.WxValidate.errorList[0];
this.showToast(error);
return false;
} else {
// 构建请求数据结构
let addressObj = {
openid: app.globalData.openid,
Name: params.Name,
phone: params.phone,
IsDefault: this.data.value,
// 详细地址
CustomArea: params.CustomArea,
// 省市区+详细地址
DeliveryAddress: DeliveryAddress + params.CustomArea,
RegionCode: storeCode
};
// console.log("跳啊: ", addressObj);
axios({
url: "/api/Account/AddAddress",
method: "POST",
data: addressObj
}, true)
.then(res => {
if (res.data.IsSuccess) {
// 发送请求获取服务器数据库中最新的收货地址列表数据
// app.getAddressList();
// 直接存储新的数据
setAddressList(res.data.ResultObject);
// 跳转到我的收获地址页面
swan.navigateBack({
// url: "/pages/address/address",
delta: 1,
success: res => {
// 添加成功
showToast("添加收货地址成功");
},
fail: () => {
// console.log("跳转失败,请重试!");
}
});
let shopcar = res.data.ResultObject
for (let i = 0, len = shopcar.length; i < len; i++) {
if (shopcar[i].IsDefaultDelivery) {
let currentMyress = {
name: shopcar[i].DeliveryConsignee, //地址名字
phone: shopcar[i].ConsigneePhone2, //地址电话
deliveryAddress: shopcar[i].DeliveryAddress, //地址
deliveryId: shopcar[i].DeliveryId, //地址id
IsDefaultDelivery: shopcar[i].IsDefaultDelivery//是否默认地址
}
swan.setStorageSync('currentMyress', currentMyress);
}
}
} else {
// 添加失败
showToast(res.data.Msg);
}
})
.catch(error => {
// console.log(error);
});
}
},
// checkedbox状态改变
checkboxChange(e) {
const { value } = e.detail;
// value是一个数组,如果length不等于0说明选中了
value.length != 0
? this.setData({ value: "true" })
: this.setData({ value: "false" });
},
/* 表单验证函数 */
initValidate() {
let rules = {
Name: {
required: true,
maxlength: 10
},
phone: {
required: true,
tel: true
},
CustomArea: {
required: true
},
receivingAddress: {
required: true
}
/* receivingAddressValue: {
required: true
} */
};
let message = {
Name: {
required: "请输入姓名",
rangelength: "请输入2~4个汉字"
},
phone: {
required: "请输入11位手机号码",
tel: "请输入正确的手机号码"
},
CustomArea: {
required: "请输入详细地址"
},
receivingAddress: {
required: "请选择收货地区"
},
receivingAddressValue: {
required: "必须选择收货地区"
}
};
//实例化当前的验证规则和提示消息
this.WxValidate = new WxValidate(rules, message);
},
// 错误消息提示框
showToast(error) {
swan.showToast({
title: error.msg,
icon: "none",
duration: 2000,
mask: false
});
},
// 获取省的数据
getProvince() {
// 从本地的省市区文件中获取省数据
let data = region.province;
data.splice(31, 4);
let provinceList = [...data]; // 将返回的数据放在一个数组里面,现在的数据结构是一个数组对象
let provinceArr = data.map(item => {
return item.name;
});
this.setData({
multiArray: [provinceArr, [], []], // 更新三维数组
provinceList, // 省原始数据
provinceArr // 省级所有名称
});
let defaultCode = this.data.provinceList[0].code;
this.setData({
currentProviceKey: defaultCode // 保存当前省级的key(也就是code)
});
this.getCity(defaultCode); // 通过省级的code获取当前省级下面的市级数据
},
getCity(code) {
// 获取市级的数据
this.setData({
currentProviceKey: code // 保存当前选择的市级code
});
// 先找到接收的code对应的市级数据
let data = region.city.filter(item => {
if (item.parentId == code) {
return true;
}
});
let cityList = [...data[0].list];
let cityArr = [...data[0].list].map(item => {
return item.name;
})
this.setData({
multiArray: [this.data.provinceArr, cityArr, []], // 更新三维数组
cityList, // 保存下市级所有数据
cityArr
});
// console.log(this.data.multiArray);
let defaultCode = this.data.cityList[0].code; // 用第一个code获取区数据
this.setData({
currentCityKey: defaultCode // 存下当前选择的城市的key
});
this.getStore(defaultCode);
},
getStore(code) {
this.setData({
// 获取区级数据
currentCityKey: code // 更新当前选择的市级Key
});
let data = region.area.filter(item => {
if (item.parentId == code) {
return true;
}
});
// console.log("store Data: ", data);
let storeList = [...data[0].list];
let storeArr = [...data[0].list].map(item => {
return item.name;
})
// console.log("区数据 >", storeArr);
this.setData({
multiArray: [this.data.provinceArr, this.data.cityArr, storeArr], // 重新赋值三级数组
storeList, // 保存区级原始数据
storeArr
});
},
columnchange(e) {
// 滚动选择器触发的事件
let column = e.detail.column; // column表示改变了第几列(下标从0开始)
let value = e.detail.value; // value的值表示变更值得下标
let multiIndex = JSON.parse(JSON.stringify(this.data.multiIndex));
multiIndex[column] = e.detail.value; // 第几列改变了就是对应multiIndex的第几个,更新他
switch (
column // 处理不同的逻辑
) {
case 0: // 第一列更改 就是省级的更改
let currentProviceKey = this.data.provinceList[e.detail.value].code; // 重新赋值省级编号
if (currentProviceKey != this.data.currentProviceKey) {
// 判断当前key是不是正真的更新
this.getCity(currentProviceKey); // 获取当前key下面的市级数据
}
multiIndex[1] = 0; // 将市默认选择第1个
this.setData(multiIndex); // 更新数据
break;
case 1: // 市发生变化
let currentCityKey = this.data.cityList[e.detail.value].code;
// let currentCityParentCode = this.data.cityList[e.detail.value].ParentCode;
if (currentCityKey != this.data.currentCityKey) {
this.getStore(currentCityKey); // 获取区
}
multiIndex[2] = 0; // 区默认选择第一个
this.setData(multiIndex); // 更新数据
break;
}
},
pickchange(e) {
// console.log("value改变了...", e.detail.value);
this.setData({
step: 1, // 更新用于是否默认显示地区的状态值
multiIndex: e.detail.value
});
}
});
addAddress.js
const app = getApp();
// 导入验证js
import WxValidate from "../../utils/WxValidate";
import { axios } from "../../utils/request";
import {
getUserInfo,
setUserInfo,
setAddressList,
getAddressList
} from "../../utils/storage";
import region from "../../utils/region";
Page({
data: {
multiArray: [], // 三维数组数据
multiIndex: [0, 0, 0], // 默认的下标 [省、市、区]
step: 0, // 默认显示请选择
// 设置默认收货地址按钮选中状态
value: "",
DeliveryId: "",
detailAddressInfo: {}
},
onLoad(params) {
// 获取传递过来的数据并赋值
const { DeliveryId } = params;
this.setData({
DeliveryId
});
this.getDetailAddressInfo();
// 初始化表单验证规则
this.initValidate();
// 获取省的数据
},
// 提交表单
formSubmit(e) {
/* if(this.data.step == 0){
swan.showToast({
title: '请选择收货城市',
icon: "none",
duration: 4000,
mask: false
});
return;
} */
let params = e.detail.value;
// 省的名字
let DeliveryName = this.data.provinceList[params["receivingAddress"][0]].name;
// 市的名字
let CityName = this.data.cityList[params["receivingAddress"][1]].name;
// 区的名字
let storeName = this.data.storeList[params["receivingAddress"][2]].name;
let DeliveryAddress;
(CityName == storeName) ? DeliveryAddress = DeliveryName + CityName : DeliveryAddress = DeliveryName + CityName + storeName;
let storeNumber = params["receivingAddress"][2];
let storeCode = this.data.storeList[storeNumber].code;
let DeliveryId = this.data.DeliveryId;
if (!this.WxValidate.checkForm(params)) {
//表单元素验证不通过,此处给出相应提示
let error = this.WxValidate.errorList[0];
this.showToast(error);
return false;
} else {
// 构建请求数据结构
let addressObj = {
openid: app.globalData.openid,
Name: params.Name,
phone: params.phone,
IsDefault: this.data.value,
// 详细地址
CustomArea: params.CustomArea,
// 省市区+详细地址
DeliveryAddress: DeliveryAddress + params.CustomArea,
RegionCode: storeCode,
DeliveryId
};
axios({
url: "/api/Account/UpdateDelivery",
method: "POST",
data: addressObj
})
.then(res => {
if (res.data.IsSuccess) {
// 获取数据库最新数据
app.getAddressList();
// 跳转到我的收获地址页面
swan.navigateBack({
url: "/pages/address/address",
delta: 1,
success: res => {
// 添加成功
swan.showToast({
title: "修改收货地址成功",
icon: "none",
duration: 2000,
mask: false
});
},
fail: () => {
// console.log("跳转失败,请重试!");
}
});
} else {
// 添加失败
this.showToast(res.data.Msg);
}
})
.catch(error => {
// console.log(error);
});
}
},
// checkedbox状态改变
checkboxChange(e) {
const { value } = e.detail;
// value是一个数组,如果length不等于0说明选中了
value.length != 0
? this.setData({ value: "true" })
: this.setData({ value: "false" });
},
/* 表单验证函数 */
initValidate() {
let rules = {
Name: {
required: true,
maxlength: 10
},
phone: {
required: true,
tel: true
},
CustomArea: {
required: true
},
receivingAddress: {
required: true
}
};
let message = {
Name: {
required: "请输入姓名",
rangelength: "请输入2~4个汉字个汉字"
},
phone: {
required: "请输入11位手机号码",
tel: "请输入正确的手机号码"
},
CustomArea: {
required: "请输入详细地址"
},
receivingAddress: {
required: "请选择收货地区"
}
};
//实例化当前的验证规则和提示消息
this.WxValidate = new WxValidate(rules, message);
},
// 错误消息提示框
showToast(error) {
swan.showToast({
title: error.msg,
icon: "none",
duration: 4000,
mask: false
});
},
// 获取省的数据
getProvince() {
let data = region.province;
data.splice(31, 4);
let provinceList = [...data]; // 将返回的数据放在一个数组里面,现在的数据结构是一个数组对象
let provinceArr = data.map(item => item.name); // 获取数据里面的value值,只用数据的名称
this.setData({
multiArray: [provinceArr, [], []], // 更新三维数组
provinceList, // 省原始数据
provinceArr // 省级所有名称
});
let defaultCode = this.data.provinceList[this.data.multiIndex[0]].code; // 使用第一项当做参数获取市级数据
this.setData({
currentProviceKey: defaultCode // 保存当前省级的key(也就是AreaCode)
});
this.getCity(defaultCode); // 通过省级的AreaCode获取当前省级下面的市级数据
},
getCity(code) {
// 获取市级的数据
this.setData({
currentProviceKey: code // 保存当前选择的市级code
});
let data = region.city.filter(item => {
if (item.parentId == code) {
return true;
}
});
let cityList = [...data[0].list];
let cityArr = [...data[0].list].map(item => {
return item.name;
});
this.setData({
multiArray: [this.data.provinceArr, cityArr, []], // 更新三维数组
cityArr, // 保存下市级所有名称
cityList // 保存下市级所有数据
});
let defaultCode = this.data.cityList[this.data.multiIndex[1]].code; // 用第一个code获取区数据
this.setData({
currentCityKey: defaultCode // 存下当前选择的城市的key
});
// 通过市级的AreaCode获取当前市级下面的区级数据
this.getStore(defaultCode);
},
getStore(code) {
// 获取区级数据
this.setData({
currentCityKey: code // 更新当前选择的市级Key
});
// 处理直辖市和特殊的区,获取区的时候使用市的code 如果不是直辖市就通过市级的AreaCode获取当前市级下面的区级数据
let data = region.area.filter(item => {
if (item.parentId == code) {
return true;
}
});
let storeList = [...data[0].list];
let storeArr = [...data[0].list].map(item => {
return item.name;
});
this.setData({
multiArray: [this.data.provinceArr, this.data.cityArr, storeArr], // 重新赋值三级数组
storeList, // 保存区级原始数据
storeArr // 保存区级名称
});
},
columnchange(e) {
// 滚动选择器触发的事件
let column = e.detail.column; // column表示改变了第几列(下标从0开始)
let value = e.detail.value; // value的值表示变更值得下标
let multiIndex = JSON.parse(JSON.stringify(this.data.multiIndex));
multiIndex[column] = e.detail.value; // 第几列改变了就是对应multiIndex的第几个,更新他
switch (
column // 处理不同的逻辑
) {
case 0: // 第一列更改 就是省级的更改
let currentProviceKey = this.data.provinceList[e.detail.value].code; // 重新赋值省级编号
if (currentProviceKey != this.data.currentProviceKey) {
// 判断当前key是不是正真的更新
this.getCity(currentProviceKey); // 获取当前key下面的市级数据
}
multiIndex[1] = 0; // 将市默认选择第1个
this.setData({ multiIndex }); // 更新数据
break;
case 1: // 市发生变化
let currentCityKey = this.data.cityList[e.detail.value].code;
if (currentCityKey != this.data.currentCityKey) {
this.getStore(currentCityKey); // 获取区
}
multiIndex[2] = 0; // 区默认选择第一个
this.setData({ multiIndex }); // 更新数据
break;
}
},
pickchange(e) {
this.setData({
step: 1, // 更新用于是否默认显示地区的状态值
multiIndex: e.detail.value
});
},
// 根据DeliveryId发请求获取收货地址详细信息
getDetailAddressInfo() {
const DeliveryId = this.data.DeliveryId;
// 减少HTTP请求,降低渲染时间
if (!this.data.detailAddressInfo.DeliveryId) {
axios({
url: "/api/Account/GetDeliveryById",
method: "POST",
data: {
openid: app.globalData.openid,
deliveryId: DeliveryId
}
})
.then(res => {
if (res.data.IsSuccess) {
let detailAddressInfo = res.data.ResultObject;
this.setData({
detailAddressInfo
});
this.getDetailAddressInfoMethod();
} else {
swan.showToast({
title: res.data.Msg,
icon: "none",
duration: 3000,
mask: false
});
}
})
.catch(error => {
// console.log(error);
});
}else {
this.getDetailAddressInfoMethod();
}
},
getDetailAddressInfoMethod() {
let RegionCode = this.data.detailAddressInfo.RegionCode;
// // 通过截取RegionCode查找省市级
let code = RegionCode.slice(0, 2) + "0000";
let provinceIndex = region.province.findIndex(item => item.code == code);
// // 获取市的数据
let cityCode = RegionCode.slice(0, 4) + "00";
let cityName = region.city.filter(item => {
return item.list.find(item2 => {
return item2.code == cityCode;
});
});
let cityIndex = cityName[0].list.findIndex(item => item.code == cityCode);
// // 获取区的数据
let storeCode = RegionCode;
let storeName = region.area.filter(item => {
return item.list.find(item2 => {
return item2.code == storeCode;
});
});
let storeIndex = storeName[0].list.findIndex(
item => item.code == storeCode
);
this.setData(
{
multiIndex: [provinceIndex, cityIndex, storeIndex]
},
() => {
this.getProvince();
}
);
// 备份
// let RegionCode = this.data.detailAddressInfo.RegionCode;
// // 通过截取RegionCode查找省市级
// let code = RegionCode.slice(0,2) + '0000';
// let provinceName = region.province.filter(item=>{
// return item.code == code;
// });
// provinceName = provinceName[0].name
// // 获取市的数据
// let cityCode = RegionCode.slice(0,4) + '00';
// let cityName = region.city.filter(item=>{
// return item.list.find(item2=>{
// return item2.code == cityCode;
// });
// })
// cityName = cityName[0].list.filter(item=>{
// return item.code == cityCode;
// })
// cityName = cityName[0].name;
// // 获取区的数据
// let storeCode = RegionCode;
// let storeName = region.area.filter(item=>{
// return item.list.find(item2=>{
// return item2.code == storeCode;
// });
// })
// storeName = storeName[0].list.filter(item=>{
// return item.code == storeCode;
// })
// storeName = storeName[0].name;
// this.setData({
// multiArray: [[provinceName], [cityName], [storeName]]
// })
},
pickClick(e) {
this.getProvince();
},
pickCancel(e) {
this.getDetailAddressInfo();
}
});
editAddress.js
编辑收获地址时获取当前地址的省市区的操作步骤是:
1.发请求拿到当前地址的信息,里面会包含一个regionCode,就是区的编号
2.通过对区的编号进行字符串截取得到市和省的编号,然后做把市很省的编号在文件里面做匹配,通过findIndex()函数找到当前对象所在数组中的下表
3.在初始函数 getDetailAddressInfoMethod中将上面三个编号所在数组对象中的index拿出来setData更新到multiIndex中即可