<template>
|
|
<view class="">
|
|
<view class="address" @click="openPopup">
|
|
|
|
<uv-icon
|
|
name="map"
|
|
size="30rpx"
|
|
:color="color"
|
|
></uv-icon>
|
|
|
|
<!-- <image src="../../static/image/home/1.png" mode=""></image> -->
|
|
<view class="eare">
|
|
<text :style="{color}">{{ selectCity.name || '请选择城市' }}</text>
|
|
</view>
|
|
<view class="down-arrow" :style="{'border-top': `15rpx solid ${color}`}"></view>
|
|
</view>
|
|
|
|
<uv-popup ref="popup" :round="30" :customStyle="{height: '60vh'}">
|
|
<view class="content">
|
|
<view class="popup-header">
|
|
<text class="popup-title">选择城市</text>
|
|
<uv-icon name="close" size="40rpx" color="#666" @click="closePopup"></uv-icon>
|
|
</view>
|
|
|
|
<scroll-view scroll-y class="city-list">
|
|
<view
|
|
v-for="(city, index) in cityList"
|
|
:key="index"
|
|
class="city-item"
|
|
:class="{ active: selectCity.id === city.id }"
|
|
@click="selectCityHandler(city)"
|
|
>
|
|
<view class="city-name">{{ city.name }}</view>
|
|
<uv-icon
|
|
v-if="selectCity.id === city.id"
|
|
name="checkmark"
|
|
size="32rpx"
|
|
color="#DC2828"
|
|
></uv-icon>
|
|
</view>
|
|
</scroll-view>
|
|
</view>
|
|
</uv-popup>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapState } from 'vuex'
|
|
|
|
/**
|
|
* 城市选择弹窗组件
|
|
*
|
|
* 使用方法:
|
|
* 1. 在页面中引入组件:
|
|
* <selectCityPopup :color="#333" @cityChange="onCityChange"></selectCityPopup>
|
|
*
|
|
* 2. 在页面的methods中监听城市变化:
|
|
* methods: {
|
|
* onCityChange(city) {
|
|
* console.log('城市切换到:', city);
|
|
* this.refreshData(); // 刷新页面数据
|
|
* },
|
|
* refreshData() {
|
|
* // 重新加载数据的逻辑
|
|
* }
|
|
* }
|
|
*
|
|
* 3. 也可以通过全局事件监听城市变化:
|
|
* mounted() {
|
|
* uni.$on('cityChanged', (city) => {
|
|
* this.refreshData();
|
|
* });
|
|
* },
|
|
* beforeDestroy() {
|
|
* uni.$off('cityChanged');
|
|
* }
|
|
*/
|
|
export default {
|
|
name: "selectCityPopup",
|
|
props : {
|
|
color : {
|
|
default : '#fff'
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
|
|
};
|
|
},
|
|
computed : {
|
|
...mapState(['cityList', 'selectCity']),
|
|
},
|
|
methods: {
|
|
// 打开弹窗
|
|
openPopup() {
|
|
// 如果城市列表为空,先获取城市列表
|
|
if (!this.cityList || this.cityList.length === 0) {
|
|
this.$store.commit('getCityList');
|
|
}
|
|
this.$refs.popup.open('bottom');
|
|
},
|
|
|
|
// 关闭弹窗
|
|
closePopup() {
|
|
this.$refs.popup.close();
|
|
},
|
|
|
|
// 选择城市
|
|
selectCityHandler(city) {
|
|
// 更新选中的城市
|
|
this.$store.commit('setCity', city);
|
|
|
|
// 关闭弹窗
|
|
this.closePopup();
|
|
|
|
// 触发城市切换事件,通知父组件刷新数据
|
|
this.$emit('cityChange', city);
|
|
|
|
// 通过全局事件总线通知其他组件刷新数据
|
|
uni.$emit('cityChanged', city);
|
|
|
|
// 显示切换成功提示
|
|
uni.showToast({
|
|
title: `已切换到${city.name}`,
|
|
icon: 'none',
|
|
duration: 1500
|
|
});
|
|
}
|
|
},
|
|
}
|
|
</script>
|
|
|
|
<style scoped lang="scss">
|
|
.address {
|
|
position: relative;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 10rpx;
|
|
cursor: pointer;
|
|
|
|
image {
|
|
height: 20rpx;
|
|
width: 20rpx;
|
|
}
|
|
|
|
.eare {
|
|
color: $uni-bg-color;
|
|
}
|
|
|
|
.down-arrow {
|
|
content: "";
|
|
display: block;
|
|
width: 0;
|
|
height: 0;
|
|
border-left: 10rpx solid transparent;
|
|
border-right: 10rpx solid transparent;
|
|
border-top: 15rpx solid $uni-bg-color;
|
|
}
|
|
}
|
|
|
|
.content {
|
|
height: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
|
|
.popup-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 30rpx 40rpx;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
|
|
.popup-title {
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
}
|
|
}
|
|
|
|
.city-list {
|
|
flex: 1;
|
|
padding: 20rpx 0;
|
|
|
|
.city-item {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 30rpx 40rpx;
|
|
border-bottom: 1px solid #f5f5f5;
|
|
transition: background-color 0.2s;
|
|
|
|
&:active {
|
|
background-color: #f8f8f8;
|
|
}
|
|
|
|
&.active {
|
|
background-color: rgba($uni-color, 0.08);
|
|
|
|
.city-name {
|
|
color: $uni-color;
|
|
font-weight: 500;
|
|
}
|
|
}
|
|
|
|
.city-name {
|
|
font-size: 30rpx;
|
|
color: #333;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|