|
|
- <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>
|