Vaya a hacer clic
representaciones
el código se muestra a continuación
en subcomponente
- en wxml
<view>
<view bindtap="handleShowCityAreaPicker">{
{provice.name}}-{
{city.name}}-{
{area.name}}</view>
</view>
<view class="city-area-picker-container {
{isShow ? 'active' : 'display-none'}}">
<view class="city-area-picker-title">区域选择器</view>
<picker-view indicator-style="height: 50px;" style="width: 100%; height: 200px;text-align:center;margin-bottom: 40px;" value="{
{currentValue}}" bindpickstart="bindpickstart" bindpickend="bindpickend" bindchange="bindChange">
<picker-view-column>
<view wx:for="{
{proviceList}}" wx:key="*this" style="line-height: 50px">{
{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{
{cityList}}" wx:key="*this" style="line-height: 50px">{
{item.name}}</view>
</picker-view-column>
<picker-view-column>
<view wx:for="{
{areaList}}" wx:key="*this" style="line-height: 50px">{
{item.name}}</view>
</picker-view-column>
</picker-view>
<view class="city-area-picker-btn-box">
<view bindtap="cancel" class="city-area-picker-cancel-btn">取消</view>
<view bindtap="confirm" class="city-area-picker-confirm-btn">确定</view>
</view>
</view>
<view class='mask' wx:if="{
{isShow}}" bindtap='closeModal'></view>
- en wxss
.mask{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 99999;
background-color: rgba(0, 0, 0, .5);
}
.city-area-picker-container {
width: 100%;
position: absolute;
bottom: 0;
left: 0;
z-index: 100000;
padding: 40rpx 60rpx;
transition: ease .3s;
transform: translateY(100%);
background-color: #fff;
box-sizing: border-box;
border-radius: 30rpx 30rpx 0 0;
}
.display-none{
display: none;
}
.city-area-picker-container.active{
transform: translateY(0);
display: block;
}
.city-area-picker-title {
text-align: center;
}
.city-area-picker-btn-box {
display: flex;
font-weight: 600;
margin-top: 40rpx;
color: var(--themeColor);
justify-content: space-around;
}
.city-area-picker-btn-box .city-area-picker-cancel-btn,
.city-area-picker-btn-box .city-area-picker-confirm-btn {
text-align: center;
font-size: 32rpx;
padding: 0 96rpx;
height: 88rpx;
line-height: 88rpx;
border-radius: 12rpx;
color: var(--themeColor);
border: 2rpx solid var(--themeColor);
}
.city-area-picker-btn-box .city-area-picker-confirm-btn{
color: #fff;
background-color: var(--themeColor);
}
page {
--themeColor: #3399ff;
}
- en js
var isScroll = false;
const cityData = require('../../utils/area.js')
// console.log(cityData)
Component({
properties: {
/**
* 日期选择器默认值
* 1. 这里设置无效 (暂时不知道什么原因) --- 问题
* 2. 所以由父组件传值过来,(* 父组件中,在 onShow() 这个生命周期中就 setData()) --- 解决
*/
// currentValue: {
// type: Array,
// value: [0,0,0]
// },
bindArr: {
type: Array,
value: [110000,110100,110111]
}
},
observers: {
'bindArr': function() {
this.initDatePicker();
}
},
data: {
isShow: false,
proviceList: [],
cityList: [],
areaList: [],
provice: null,
city: null,
area: null,
currentValue: [0,0,0]
},
lifetimes: {
attached: function () {
this.formatCityData(cityData)
},
moved: function () {
},
detached: function () {
},
},
methods: {
// 格式化全国省市区数据
formatCityData(cityData = []) {
const currentValue = this.data.currentValue
const proviceList = this.filterData(cityData)
// console.log('动态更新 currentValue', currentValue)
// console.log('当前省份下的省市区:', cityData[currentValue[0]])
const cityList = this.filterData(cityData[currentValue[0]].children)
const areaList = this.filterData(cityData[currentValue[0]].children[currentValue[1]].children)
const provice = proviceList[currentValue[0]]
const city = cityList[currentValue[1]]
const area = areaList[currentValue[2]]
this.setData({
proviceList, cityList, areaList, provice, city, area })
},
// 格式化全国省市区数据 辅助函数
filterData(arr = []) {
const list = []
if (!arr) return []
arr.forEach(v => {
let obj = {
}
obj.name = v.name
obj.code = v.code
list.push(obj)
})
return list
},
/***
* 滚动选择时触发change事件,
* 可以查看小程序官方文档了解
*/
bindChange(e) {
console.log(e)
const val = e.detail.value;
let {
currentValue } = this.data
console.log('val:', val)
console.log('currentValue:',currentValue)
if (val[0] !== currentValue[0]) {
currentValue = [val[0], 0, 0]
this.setData({
currentValue })
} else if (val[1] !== currentValue[1]) {
currentValue = [val[0], val[1], 0]
this.setData({
currentValue })
} else if (val[2] !== currentValue[2]) {
currentValue = val
this.setData({
currentValue })
}
this.formatCityData(cityData)
},
// 滚动开始
bindpickstart(){
isScroll = true
},
//滚动结束
bindpickend(){
isScroll = false
},
// 打开 省市区三级联动 选择器
handleShowCityAreaPicker() {
this.setData({
isShow: true})
const pIndex = this.data.proviceList.findIndex(v => v.code == this.data.bindArr[0])
const cityList = cityData[pIndex].children
const cIndex = cityList.findIndex(v => v.code == this.data.bindArr[1])
const areaList = cityList[cIndex].children
const aIndex = areaList.findIndex(v => v.code == this.data.bindArr[2])
this.setData({
cityList, areaList })
this.setData({
currentValue: [pIndex, cIndex, aIndex] })
},
// 点击取消按钮,关闭日期选择器
cancel() {
this.setData({
isShow: false})
},
// 点击确定按钮
confirm() {
let {
provice, city, area } = this.data
// 判断用户选择时间滚动是否结束,解决 picker-view bindChange 延迟问题
if (isScroll) return
this.triggerEvent('handleSelectDate', {
provice, city, area })
this.setData({
isShow: false})
},
// 点击遮罩层,关闭日期选择器
closeModal() {
this.setData({
isShow: false})
},
// 初始化 picker 日期数据
initDatePicker() {
if (this.data.bindArr.length !== 0) {
console.log(this.data.bindArr)
const pItem = this.data.proviceList.find(v => v.code == this.data.bindArr[0])
const pIndex = this.data.proviceList.findIndex(v => v.code == this.data.bindArr[0])
let cItem = cityData[pIndex].children.find(v => v.code == this.data.bindArr[1])
let aItem = cItem.children.find(v => v.code == this.data.bindArr[2])
cItem = this.filterData([cItem])[0]
aItem = this.filterData([aItem])[0]
this.setData({
provice: pItem, city: cItem, area: aItem})
}
},
},
});
en el componente principal
- en wxml
<view>
<picker-city-area-pro bind:handleSelectDate="handleSelectDate" bindArr="{
{bindArr}}"></picker-city-area-pro>
</view>
- en json
{
"navigationBarTitleText": "省市区联动",
"usingComponents": {
"picker-city-area-pro": "/components/picker-city-area-pro"
}
}
- en js
Page({
data: {
proviceId: '', // 省 code
cityId: '', // 省 code
areaId: '', // 省 code
bindArr: [] //用于回显 省市区
},
handleSelectDate(e) {
console.log(e.detail);
const {
provice, city, area } = e.detail
this.setData({
proviceId: provice.code,
cityId: city.code,
areaId: area.code
})
},
// 页面初始化事件
onLoad: function () {
// 设置默认城市,不设置的默认会是 北京市-北京市-房山区
this.setData({
bindArr: ['420000', '420100', '420111']
})
},
onShow: function () {
}
});