建材商城系统20241014
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
4.3 KiB

  1. <template>
  2. <view class="">
  3. <view class="address" @click="openPopup">
  4. <uv-icon
  5. name="map"
  6. size="30rpx"
  7. :color="color"
  8. ></uv-icon>
  9. <!-- <image src="../../static/image/home/1.png" mode=""></image> -->
  10. <view class="eare">
  11. <text :style="{color}">{{ selectCity.name || '请选择城市' }}</text>
  12. </view>
  13. <view class="down-arrow" :style="{'border-top': `15rpx solid ${color}`}"></view>
  14. </view>
  15. <uv-popup ref="popup" :round="30" :customStyle="{height: '60vh'}">
  16. <view class="content">
  17. <view class="popup-header">
  18. <text class="popup-title">选择城市</text>
  19. <uv-icon name="close" size="40rpx" color="#666" @click="closePopup"></uv-icon>
  20. </view>
  21. <scroll-view scroll-y class="city-list">
  22. <view
  23. v-for="(city, index) in cityList"
  24. :key="index"
  25. class="city-item"
  26. :class="{ active: selectCity.id === city.id }"
  27. @click="selectCityHandler(city)"
  28. >
  29. <view class="city-name">{{ city.name }}</view>
  30. <uv-icon
  31. v-if="selectCity.id === city.id"
  32. name="checkmark"
  33. size="32rpx"
  34. color="#DC2828"
  35. ></uv-icon>
  36. </view>
  37. </scroll-view>
  38. </view>
  39. </uv-popup>
  40. </view>
  41. </template>
  42. <script>
  43. import { mapState } from 'vuex'
  44. /**
  45. * 城市选择弹窗组件
  46. *
  47. * 使用方法
  48. * 1. 在页面中引入组件
  49. * <selectCityPopup :color="#333" @cityChange="onCityChange"></selectCityPopup>
  50. *
  51. * 2. 在页面的methods中监听城市变化
  52. * methods: {
  53. * onCityChange(city) {
  54. * console.log('城市切换到:', city);
  55. * this.refreshData(); // 刷新页面数据
  56. * },
  57. * refreshData() {
  58. * // 重新加载数据的逻辑
  59. * }
  60. * }
  61. *
  62. * 3. 也可以通过全局事件监听城市变化
  63. * mounted() {
  64. * uni.$on('cityChanged', (city) => {
  65. * this.refreshData();
  66. * });
  67. * },
  68. * beforeDestroy() {
  69. * uni.$off('cityChanged');
  70. * }
  71. */
  72. export default {
  73. name: "selectCityPopup",
  74. props : {
  75. color : {
  76. default : '#fff'
  77. }
  78. },
  79. data() {
  80. return {
  81. };
  82. },
  83. computed : {
  84. ...mapState(['cityList', 'selectCity']),
  85. },
  86. methods: {
  87. // 打开弹窗
  88. openPopup() {
  89. // 如果城市列表为空,先获取城市列表
  90. if (!this.cityList || this.cityList.length === 0) {
  91. this.$store.commit('getCityList');
  92. }
  93. this.$refs.popup.open('bottom');
  94. },
  95. // 关闭弹窗
  96. closePopup() {
  97. this.$refs.popup.close();
  98. },
  99. // 选择城市
  100. selectCityHandler(city) {
  101. // 更新选中的城市
  102. this.$store.commit('setCity', city);
  103. // 关闭弹窗
  104. this.closePopup();
  105. // 触发城市切换事件,通知父组件刷新数据
  106. this.$emit('cityChange', city);
  107. // 通过全局事件总线通知其他组件刷新数据
  108. uni.$emit('cityChanged', city);
  109. // 显示切换成功提示
  110. uni.showToast({
  111. title: `已切换到${city.name}`,
  112. icon: 'none',
  113. duration: 1500
  114. });
  115. }
  116. },
  117. }
  118. </script>
  119. <style scoped lang="scss">
  120. .address {
  121. position: relative;
  122. display: flex;
  123. align-items: center;
  124. justify-content: center;
  125. gap: 10rpx;
  126. cursor: pointer;
  127. image {
  128. height: 20rpx;
  129. width: 20rpx;
  130. }
  131. .eare {
  132. color: $uni-bg-color;
  133. }
  134. .down-arrow {
  135. content: "";
  136. display: block;
  137. width: 0;
  138. height: 0;
  139. border-left: 10rpx solid transparent;
  140. border-right: 10rpx solid transparent;
  141. border-top: 15rpx solid $uni-bg-color;
  142. }
  143. }
  144. .content {
  145. height: 100%;
  146. display: flex;
  147. flex-direction: column;
  148. .popup-header {
  149. display: flex;
  150. justify-content: space-between;
  151. align-items: center;
  152. padding: 30rpx 40rpx;
  153. border-bottom: 1px solid #f0f0f0;
  154. .popup-title {
  155. font-size: 32rpx;
  156. font-weight: 600;
  157. color: #333;
  158. }
  159. }
  160. .city-list {
  161. flex: 1;
  162. padding: 20rpx 0;
  163. .city-item {
  164. display: flex;
  165. justify-content: space-between;
  166. align-items: center;
  167. padding: 30rpx 40rpx;
  168. border-bottom: 1px solid #f5f5f5;
  169. transition: background-color 0.2s;
  170. &:active {
  171. background-color: #f8f8f8;
  172. }
  173. &.active {
  174. background-color: rgba($uni-color, 0.08);
  175. .city-name {
  176. color: $uni-color;
  177. font-weight: 500;
  178. }
  179. }
  180. .city-name {
  181. font-size: 30rpx;
  182. color: #333;
  183. }
  184. }
  185. }
  186. }
  187. </style>