|
|
@@ -1,8 +1,41 @@
|
|
|
<template>
|
|
|
<view class="addressPicker">
|
|
|
- <u-picker :show="shows" ref="uPicker" :defaultIndex="defaultIndex" :columns="columns" keyName="name"
|
|
|
+ <u-popup :show="modelshow" @close="close" round="20rpx" bgColor="#fff" mode="bottom"
|
|
|
+ :closeOnClickOverlay="true">
|
|
|
+ <view class="">
|
|
|
+ <view class="header header-padding dis a-c j-c borderBottom">
|
|
|
+ <text>选择地区</text>
|
|
|
+ </view>
|
|
|
+ <view class="content">
|
|
|
+ <view class="quickOptions">
|
|
|
+ <picker-view :indicator-style="indicatorStyle" :value="value" @change="monthbindChange"
|
|
|
+ class="picker-view">
|
|
|
+ <picker-view-column>
|
|
|
+ <view class="item dis a-c j-c " v-for="(item,index) in columns[0]" :key="index">
|
|
|
+ {{item.name}}
|
|
|
+ </view>
|
|
|
+ </picker-view-column>
|
|
|
+ <picker-view-column>
|
|
|
+ <view class="item dis a-c j-c " v-for="(item,index) in columns[1]" :key="index">
|
|
|
+ {{item.name}}
|
|
|
+ </view>
|
|
|
+ </picker-view-column>
|
|
|
+ <picker-view-column>
|
|
|
+ <view class="item dis a-c j-c " v-for="(item,index) in columns[2]" :key="index">
|
|
|
+ {{item.name}}
|
|
|
+ </view>
|
|
|
+ </picker-view-column>
|
|
|
+ </picker-view>
|
|
|
+ <view class="custom-footer dis j-s a-c ">
|
|
|
+ <view class="dis a-c j-c" @tap="statusConfirm">确定</view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ </u-popup>
|
|
|
+ <!-- <u-picker :show="shows" ref="uPicker" :defaultIndex="defaultIndex" :columns="columns" keyName="name"
|
|
|
@change="changeHandler" @cancel="cancel" @confirm="confirm" @close="close"
|
|
|
- :closeOnClickOverlay="true"></u-picker>
|
|
|
+ :closeOnClickOverlay="true"></u-picker> -->
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
@@ -25,18 +58,21 @@
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
- shows: this.show,
|
|
|
+ modelshow: this.show,
|
|
|
columns: [
|
|
|
[],
|
|
|
[],
|
|
|
[]
|
|
|
], // 省/市/区三级数据
|
|
|
- fullData: [] // 包含完整结构的缓存数据
|
|
|
+ fullData: [], // 包含完整结构的缓存数据
|
|
|
+ value: [0, 0, 0],
|
|
|
+ lastValue: [0, 0, 0], // 保存上一次的选中值
|
|
|
+ indicatorStyle: `height: 41px;`
|
|
|
}
|
|
|
},
|
|
|
watch: {
|
|
|
show(val) {
|
|
|
- this.shows = val
|
|
|
+ this.modelshow = val
|
|
|
if (val) this.initByCodes(this.defaultCodes)
|
|
|
},
|
|
|
defaultCodes: {
|
|
|
@@ -48,8 +84,65 @@
|
|
|
},
|
|
|
async created() {
|
|
|
await this.initData()
|
|
|
+ console.log(this.fullData);
|
|
|
},
|
|
|
methods: {
|
|
|
+ //月份滚动事件
|
|
|
+ monthbindChange: function(e) {
|
|
|
+ const val = e.detail.value; // 当前选中下标数组 [省索引, 市索引, 区索引]
|
|
|
+ const lastVal = this.lastValue;
|
|
|
+
|
|
|
+ let provinceIndex = val[0];
|
|
|
+ let cityIndex = val[1];
|
|
|
+ let areaIndex = val[2] || 0;
|
|
|
+
|
|
|
+ // 判断是否是省份变化
|
|
|
+ if (provinceIndex !== lastVal[0]) {
|
|
|
+ if (this.fullData[provinceIndex]) {
|
|
|
+ const cities = this.fullData[provinceIndex].children || [];
|
|
|
+ this.columns[1] = cities.map(c => ({
|
|
|
+ name: c.name,
|
|
|
+ code: c.code
|
|
|
+ }));
|
|
|
+
|
|
|
+ // 重置城市索引到第一个
|
|
|
+ cityIndex = 0;
|
|
|
+
|
|
|
+ // 更新区级数据
|
|
|
+ if (cities[0]) {
|
|
|
+ const areas = cities[0].children || [];
|
|
|
+ this.columns[2] = areas.map(a => ({
|
|
|
+ name: a.name,
|
|
|
+ code: a.code
|
|
|
+ }));
|
|
|
+ areaIndex = 0;
|
|
|
+ } else {
|
|
|
+ this.columns[2] = [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 判断是否是城市变化
|
|
|
+ else if (cityIndex !== lastVal[1]) {
|
|
|
+ if (this.fullData[provinceIndex]?.children?.[cityIndex]) {
|
|
|
+ const areas = this.fullData[provinceIndex].children[cityIndex].children || [];
|
|
|
+ this.columns[2] = areas.map(a => ({
|
|
|
+ name: a.name,
|
|
|
+ code: a.code
|
|
|
+ }));
|
|
|
+ areaIndex = 0;
|
|
|
+ } else {
|
|
|
+ this.columns[2] = [];
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 保存当前值
|
|
|
+ this.lastValue = [provinceIndex, cityIndex, areaIndex];
|
|
|
+
|
|
|
+ // 使用nextTick延迟更新value,避免阻塞用户滑动
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.value = [provinceIndex, cityIndex, areaIndex];
|
|
|
+ });
|
|
|
+ },
|
|
|
// 初始化数据结构(含6位码处理)
|
|
|
initData() {
|
|
|
this.fullData = address.map(province => ({
|
|
|
@@ -168,6 +261,23 @@
|
|
|
this.$refs.uPicker.setColumnValues(2, this.columns[2])
|
|
|
}
|
|
|
},
|
|
|
+ statusConfirm() {
|
|
|
+ const provinceIndex = this.value[0] || 0;
|
|
|
+ const cityIndex = this.value[1] || 0;
|
|
|
+ const areaIndex = this.value[2] || 0;
|
|
|
+
|
|
|
+ const province = this.columns[0][provinceIndex];
|
|
|
+ const city = this.columns[1][cityIndex];
|
|
|
+ const area = this.columns[2][areaIndex];
|
|
|
+
|
|
|
+ this.$emit('confirm', {
|
|
|
+ names: [province?.name, city?.name, area?.name].filter(Boolean),
|
|
|
+ codes: [province?.code, city?.code, area?.code].filter(Boolean),
|
|
|
+ fullAddress: [province?.name, city?.name, area?.name].filter(Boolean).join('-')
|
|
|
+ });
|
|
|
+
|
|
|
+ this.close();
|
|
|
+ },
|
|
|
cancel() {
|
|
|
this.$emit('cancel')
|
|
|
},
|
|
|
@@ -188,5 +298,61 @@
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
+ .header {
|
|
|
+ color: #333;
|
|
|
+ font-size: 32rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ }
|
|
|
+
|
|
|
+ .header-padding {
|
|
|
+ padding: 27rpx 30rpx;
|
|
|
+ }
|
|
|
|
|
|
+ .borderBottom {
|
|
|
+ border-bottom: 1px solid #EEEEEE;
|
|
|
+ }
|
|
|
+
|
|
|
+ .quickOptions {
|
|
|
+ padding: 32rpx;
|
|
|
+ box-sizing: border-box;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ .custom-footer {
|
|
|
+ padding: 40rpx 0 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+
|
|
|
+ view {
|
|
|
+ font-size: 30rpx;
|
|
|
+ padding: 20rpx;
|
|
|
+ flex: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ view:first-child {
|
|
|
+ color: #333;
|
|
|
+ background: transparent;
|
|
|
+ border-radius: 50rpx;
|
|
|
+ border: 1rpx solid #FDE935;
|
|
|
+ margin-right: 28rpx;
|
|
|
+ }
|
|
|
+
|
|
|
+ view:last-child {
|
|
|
+ background: #FDE935;
|
|
|
+ border-radius: 50rpx;
|
|
|
+ color: #1F1F1F;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .picker-view {
|
|
|
+ width: 100%;
|
|
|
+ height: 400rpx;
|
|
|
+
|
|
|
+ .item {
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #333;
|
|
|
+ }
|
|
|
+ }
|
|
|
</style>
|