记录一下地址选择组件,代码质量也许不高,欢迎学习交流。
组件部分代码如下:
<template>
<u-popup :show="show" :round="10" @close="close" closeable>
<view class="address">
<view>选择地区</view>
<!-- 定位展示 -->
<view class="address-location">
<u-icon name="map-fill" color="#06A88B" size="22"></u-icon>
<view class="address-Info"> 定位失败 </view>
</view>
<!-- 省份/地区 -->
<view class="address-content">
<!-- 选中后显示区域 -->
<view class="address-selected">
<view v-if="selectedLists.length === 0" style="color: #7f848e"
>省份/地区</view
>
<view
v-for="(item, index) in selectedLists"
:key="index"
:class="['ellipsis', changeIndex == index + 1 ? 'bold' : '']"
@click="changeAddress(index)"
>{{ item.name }}</view
>
<view
v-if="selectedLists.length == 1"
@click="changeAddress(1)"
class="tip-msg"
>城市</view
>
<view
v-if="selectedLists.length == 2"
@click="changeAddress(2)"
class="tip-msg"
>区/县</view
>
<view
v-if="selectedLists.length == 3 && selectedLists[2].children"
@click="changeAddress(3)"
class="tip-msg"
>街道/镇</view
>
</view>
<!-- 地区列表 -->
<view class="address-list">
<swiper @change="slideOn" :current="changeIndex2" class="swiper">
<swiper-item
v-for="(tab, tabIndex) in saveHistoryTreeStack"
:key="tabIndex"
>
<scroll-view scroll-y="true" class="scroll-Y">
<view
v-for="item in saveHistoryTreeStack[tabIndex]"
:key="item.name"
@click="clickItem(item, tabIndex)"
class="address-item"
>{{ item.name }}
<u-icon
v-if="selectedLists.includes(item)"
name="checkmark"
color="#06A88B"
size="26"
></u-icon>
</view>
</scroll-view>
</swiper-item>
</swiper>
</view>
</view>
</view>
</u-popup>
</template>
<script>
// 导入省市区街道数据树
import cityTree from "../common/cityTree.js";
export default {
props: {
show: {
type: Boolean,
default: false,
},
},
data() {
return {
selectedLists: [],
changeIndex: null,
saveHistoryTreeStack: [], // 保存点击的记录栈
changeIndex2: 0,
};
},
created() {
this.getTree();
},
methods: {
getTree() {
this.saveHistoryTreeStack[0] = cityTree;
},
slideOn(e) {
this.changeAddress(e.detail.current);
},
// 选中地址
clickItem(item, tabIndex) {
if (this.changeIndex) {
if (this.changeIndex == 1) {
this.selectedLists = [];
this.selectedLists[0] = item;
} else if (this.changeIndex == 2) {
this.selectedLists = [this.selectedLists[0], item];
} else if (this.changeIndex == 3) {
this.selectedLists = [
this.selectedLists[0],
this.selectedLists[1],
item,
];
} else if (this.changeIndex == 4) {
this.selectedLists[3] = item;
}
} else {
this.selectedLists[tabIndex] = item;
}
if (this.selectedLists.length == 1) {
this.saveHistoryTreeStack[1] = this.selectedLists[0].children;
} else if (this.selectedLists.length == 2) {
this.saveHistoryTreeStack[2] = this.selectedLists[1].children;
} else if (this.selectedLists.length == 3) {
this.saveHistoryTreeStack[3] = this.selectedLists[2].children;
}
this.$forceUpdate();
if (item.children) {
this.changeIndex = null;
// 用于改变 swiper组件的current值
this.$nextTick(() => {
this.changeIndex2 = tabIndex + 1;
});
} else {
const selectedArr = this.selectedLists.map((v) => {
return v.name;
});
this.$emit("sendAddress", selectedArr);
this.changeIndex = this.selectedLists.length;
}
},
// 切换地址
changeAddress(index) {
this.changeIndex = index + 1;
this.changeIndex2 = index;
},
close() {
this.$emit("sendAddress");
},
},
};
</script>
<style lang="scss" scoped>
.address {
padding-top: 30rpx;
text-align: center;
&-location {
display: flex;
margin: 26rpx 40rpx 4rpx 40rpx;
align-items: center;
background: #faf5f8;
border-radius: 20rpx;
box-sizing: border-box;
font-size: 30rpx;
padding: 20rpx 28rpx;
}
&-Info {
margin-left: 20rpx;
}
&-content {
font-size: 30rpx;
}
&-selected {
display: flex;
align-items: center;
border-bottom: 2rpx solid rgb(243, 241, 241);
padding: 30rpx 48rpx;
box-sizing: border-box;
.tip-msg {
color: gainsboro;
}
}
&-item {
border-bottom: 2rpx solid rgb(243, 241, 241);
padding: 0 48rpx;
height: 80rpx;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: space-between;
}
.ellipsis {
width: 25%;
box-sizing: border-box;
text-align: left;
}
.bold {
font-weight: 700;
color: #06a88b;
}
}
.swiper {
height: 740rpx;
}
.scroll-Y {
height: 720rpx;
}
</style>