citySelect.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. <template>
  2. <view class="city-select-page">
  3. <!-- 城市选择头部 -->
  4. <view class="city-header">
  5. <view class="header-content">
  6. <view class="header-left" @click="goBack">
  7. <u-icon name="close" color="#333" size="32"></u-icon>
  8. </view>
  9. <view class="header-title">城市选择</view>
  10. <view class="header-right"></view>
  11. </view>
  12. </view>
  13. <!-- 三列选择区域 -->
  14. <view class="city-list">
  15. <!-- 左侧城市列 -->
  16. <view class="city-column city-column-left">
  17. <scroll-view scroll-y="true" style="width: 100%;height: 100%;padding-bottom: 20rpx;">
  18. <view
  19. class="city-item"
  20. @click="selectCity(index)"
  21. :class="currentCity==index?'active':''"
  22. v-for="(item,index) in cityList"
  23. :key="index"
  24. >
  25. {{item.name}}
  26. </view>
  27. </scroll-view>
  28. </view>
  29. <!-- 中间区域列 -->
  30. <view class="city-column city-column-middle">
  31. <view class="city-column-container">
  32. <!-- 区域标题列 -->
  33. <view class="city-column-titles">
  34. <scroll-view scroll-y="true" style="width: 100%;height: 100%;padding-bottom: 20rpx;">
  35. <view
  36. class="city-title-item"
  37. @click="setActiveDistrict(index)"
  38. :class="activeDistrict==index?'active':''"
  39. v-for="(item,index) in districtList"
  40. :key="index"
  41. >
  42. {{item.name}}
  43. </view>
  44. </scroll-view>
  45. </view>
  46. <!-- 最右侧子区域列 -->
  47. <view class="city-column-content">
  48. <scroll-view scroll-y="true" style="width: 100%;height: 100%;padding-bottom: 20rpx;">
  49. <view class="city-sub-items" v-if="districtList.length>0 && districtList[activeDistrict]">
  50. <view
  51. class="city-sub-item"
  52. @click="selectSubArea(item)"
  53. :class="selectedSubAreas.includes(item.name)?'selected':''"
  54. v-for="(item,ind) in districtList[activeDistrict].subAreas"
  55. :key="ind"
  56. >
  57. {{item.name}}
  58. </view>
  59. </view>
  60. </scroll-view>
  61. </view>
  62. </view>
  63. </view>
  64. </view>
  65. <!-- 底部确定按钮 -->
  66. <view class="bottom-btn-container">
  67. <view class="confirm-btn" @click="confirmSelection">
  68. <text>确定</text>
  69. </view>
  70. </view>
  71. </view>
  72. </template>
  73. <script>
  74. export default {
  75. data() {
  76. return {
  77. currentCity: 0,
  78. activeDistrict: 0,
  79. selectedSubAreas: ['蛇口', '海岸城'],
  80. cityList: [
  81. { name: '深圳', code: 'sz' },
  82. { name: '广州', code: 'gz' },
  83. ],
  84. districtList: [
  85. {
  86. name: '全深圳',
  87. subAreas: [
  88. { name: '全南山' },
  89. { name: '科技园' },
  90. { name: '西丽' },
  91. { name: '前海' },
  92. { name: '蛇口' },
  93. { name: '大学城' },
  94. { name: '海岸城' },
  95. { name: '南山中心' },
  96. { name: '华侨城' },
  97. { name: '南油' },
  98. { name: '海上世界' },
  99. { name: '欢乐海岸' },
  100. { name: '后海' },
  101. { name: '大冲' }
  102. ]
  103. },
  104. {
  105. name: '南山区',
  106. subAreas: [
  107. { name: '全南山' },
  108. { name: '科技园' },
  109. { name: '西丽' },
  110. { name: '前海' },
  111. { name: '蛇口' },
  112. { name: '大学城' },
  113. { name: '海岸城' },
  114. { name: '南山中心' },
  115. { name: '华侨城' },
  116. { name: '南油' },
  117. { name: '海上世界' },
  118. { name: '欢乐海岸' },
  119. { name: '后海' },
  120. { name: '大冲' }
  121. ]
  122. },
  123. {
  124. name: '龙岗区',
  125. subAreas: [
  126. { name: '全龙岗' },
  127. { name: '布吉' },
  128. { name: '坂田' },
  129. { name: '横岗' },
  130. { name: '龙城' },
  131. { name: '坪地' },
  132. { name: '平湖' }
  133. ]
  134. },
  135. {
  136. name: '宝安区',
  137. subAreas: [
  138. { name: '全宝安' },
  139. { name: '西乡' },
  140. { name: '福永' },
  141. { name: '沙井' },
  142. { name: '松岗' },
  143. { name: '石岩' }
  144. ]
  145. },
  146. {
  147. name: '福田区',
  148. subAreas: [
  149. { name: '全福田' },
  150. { name: '华强北' },
  151. { name: '车公庙' },
  152. { name: '中心区' },
  153. { name: '皇岗' },
  154. { name: '梅林' }
  155. ]
  156. },
  157. {
  158. name: '龙华区',
  159. subAreas: [
  160. { name: '全龙华' },
  161. { name: '民治' },
  162. { name: '大浪' },
  163. { name: '观澜' },
  164. { name: '福城' }
  165. ]
  166. },
  167. {
  168. name: '罗湖区',
  169. subAreas: [
  170. { name: '全罗湖' },
  171. { name: '东门' },
  172. { name: '国贸' },
  173. { name: '翠竹' },
  174. { name: '莲塘' }
  175. ]
  176. },
  177. {
  178. name: '光明区',
  179. subAreas: [
  180. { name: '全光明' },
  181. { name: '公明' },
  182. { name: '光明' },
  183. { name: '新湖' }
  184. ]
  185. },
  186. {
  187. name: '坪山区',
  188. subAreas: [
  189. { name: '全坪山' },
  190. { name: '坪山' },
  191. { name: '坑梓' }
  192. ]
  193. },
  194. {
  195. name: '盐田区',
  196. subAreas: [
  197. { name: '全盐田' },
  198. { name: '盐田' },
  199. { name: '沙头角' }
  200. ]
  201. }
  202. ]
  203. };
  204. },
  205. methods: {
  206. /**
  207. * 返回上一页
  208. */
  209. goBack() {
  210. uni.navigateBack()
  211. },
  212. /**
  213. * 选择城市
  214. */
  215. selectCity(index) {
  216. this.currentCity = index
  217. this.activeDistrict = 0
  218. this.selectedSubAreas = []
  219. },
  220. /**
  221. * 选择区域
  222. */
  223. setActiveDistrict(index) {
  224. this.activeDistrict = index
  225. },
  226. /**
  227. * 选择子区域
  228. */
  229. selectSubArea(item) {
  230. const index = this.selectedSubAreas.indexOf(item.name)
  231. if (index > -1) {
  232. this.selectedSubAreas.splice(index, 1)
  233. } else {
  234. this.selectedSubAreas.push(item.name)
  235. }
  236. },
  237. /**
  238. * 确认选择
  239. */
  240. confirmSelection() {
  241. console.log('选中的城市:', this.cityList[this.currentCity])
  242. console.log('选中的区域:', this.districtList[this.activeDistrict])
  243. console.log('选中的子区域:', this.selectedSubAreas)
  244. uni.showToast({
  245. title: '选择成功',
  246. icon: 'success'
  247. })
  248. setTimeout(() => {
  249. uni.navigateBack()
  250. }, 1500)
  251. }
  252. }
  253. }
  254. </script>
  255. <style lang="scss">
  256. page {
  257. background-color: #FCFCFC;
  258. padding: 0 20rpx;
  259. }
  260. .city-select-page {
  261. min-height: 100vh;
  262. }
  263. .city-header {
  264. padding-top: 80rpx;
  265. background-color: #FCFCFC;
  266. z-index: 9999;
  267. box-sizing: border-box;
  268. margin-bottom: 40rpx;
  269. .header-content {
  270. display: flex;
  271. align-items: center;
  272. justify-content: space-between;
  273. height: 100%;
  274. .header-left, .header-right {
  275. width: 60rpx;
  276. height: 60rpx;
  277. display: flex;
  278. align-items: center;
  279. justify-content: center;
  280. }
  281. .header-title {
  282. color: rgba(51, 51, 51, 1);
  283. font-family: DM Sans;
  284. font-size: 36rpx;
  285. font-weight: 700;
  286. line-height: 26px;
  287. letter-spacing: 0px;
  288. text-align: center;
  289. }
  290. }
  291. }
  292. .city-list {
  293. width: 100%;
  294. height: calc(100vh - 200rpx);
  295. gap: 16rpx;
  296. display: flex;
  297. .city-column {
  298. border-radius: 6px;
  299. // background-color: #ffffff;
  300. // border-left: 1rpx solid #F2F2F7;
  301. box-sizing: border-box;
  302. &.city-column-left {
  303. width: 25%;
  304. height: 90%;
  305. background: rgba(245, 245, 245, 1);
  306. border-left: none;
  307. padding-top: 42rpx;
  308. .city-item {
  309. color: rgba(102, 102, 102, 1);
  310. font-family: DM Sans;
  311. font-size: 32rpx;
  312. font-weight: 400;
  313. line-height: 42rpx;
  314. letter-spacing: 0%;
  315. text-align: center;
  316. padding: 16rpx 0;
  317. margin-bottom: 16rpx;
  318. &.active {
  319. color: rgba(1, 107, 246, 1);
  320. font-family: DM Sans;
  321. font-size: 32rpx;
  322. font-weight: 400;
  323. line-height: 42rpx;
  324. letter-spacing: 0%;
  325. text-align: center;
  326. padding: 16rpx auto;
  327. margin-bottom: 16rpx;
  328. }
  329. }
  330. }
  331. &.city-column-middle {
  332. width: 75%;
  333. height: 90%;
  334. // gap: 16rpx;
  335. .city-column-container {
  336. width: 100%;
  337. height: 100%;
  338. display: flex;
  339. flex-direction: row;
  340. }
  341. .city-column-titles {
  342. width: 50%;
  343. height: 100%;
  344. background: rgba(255, 255, 255, 1);
  345. // border-right: 1rpx solid #F2F2F7;
  346. box-sizing: border-box;
  347. margin-right: 16rpx;
  348. border-radius: 12rpx;
  349. box-shadow: 0px 8px 150px 0px rgba(0, 0, 0, 0.05);
  350. padding-top: 42rpx;
  351. .city-title-item {
  352. color: rgba(153, 153, 153, 1);
  353. font-family: DM Sans;
  354. font-size: 32rpx;
  355. font-weight: 400;
  356. line-height: 42rpx;
  357. letter-spacing: 0%;
  358. text-align: left;
  359. padding: 16rpx 0 16rpx 40rpx;
  360. &.active {
  361. color: rgba(1, 107, 246, 1);
  362. background: rgba(153, 196, 250, 0.4);
  363. font-family: DM Sans;
  364. font-size: 32rpx;
  365. font-weight: 400;
  366. line-height: 42rpx;
  367. letter-spacing: 0%;
  368. text-align: left;
  369. padding: 16rpx 0 16rpx 40rpx;
  370. }
  371. }
  372. }
  373. .city-column-content {
  374. width: 70%;
  375. height: 100%;
  376. background: #F5F5F5;
  377. border-radius: 12rpx;
  378. box-shadow: 0px 8px 150px 0px rgba(0, 0, 0, 0.05);
  379. flex: 1;
  380. .city-sub-items {
  381. width: 100%;
  382. display: flex;
  383. flex-direction: column;
  384. gap: 12rpx;
  385. padding-top: 42rpx;
  386. .city-sub-item {
  387. color: rgba(153, 153, 153, 1);
  388. font-family: DM Sans;
  389. font-size: 32rpx;
  390. font-weight: 400;
  391. line-height: 42rpx;
  392. letter-spacing: 0%;
  393. text-align: left;
  394. padding: 16rpx 0 16rpx 40rpx;
  395. &.selected {
  396. color: rgba(255, 255, 255, 1);
  397. border-radius: 0px 6px 6px 0px;
  398. background: rgba(1, 107, 246, 1);
  399. }
  400. }
  401. }
  402. }
  403. }
  404. }
  405. }
  406. .bottom-btn-container {
  407. position: fixed;
  408. bottom: 0;
  409. left: 0;
  410. right: 0;
  411. padding: 30rpx 20rpx;
  412. background: #fff;
  413. border-top: 1px solid #f0f0f0;
  414. z-index: 9999;
  415. }
  416. .confirm-btn {
  417. width: 100%;
  418. height: 88rpx;
  419. background: var(--线性渐变, linear-gradient(90.00deg, rgba(13, 39, 247, 1),rgba(19, 193, 234, 1) 100%));
  420. border-radius: 44rpx;
  421. display: flex;
  422. align-items: center;
  423. justify-content: center;
  424. text {
  425. font-size: 32rpx;
  426. font-weight: 600;
  427. color: #fff;
  428. }
  429. }
  430. </style>