city.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507
  1. <template>
  2. <view>
  3. <view class="header w100 flexw" :style="{height:customBar}">
  4. <view class="placeholder" :style="{height:statusBar}"></view>
  5. <view class="flex w100 mt-20">
  6. <input class="input" @confirm="doneInput" type="text" confirm-type="search" :adjust-position="false" @input="onInput"
  7. placeholder="搜索城市 中文/首字母" v-model="searchValue" />
  8. <view class="back_div fsmall bold blue" @tap="confirm_city">
  9. 确定
  10. </view>
  11. </view>
  12. </view>
  13. <scroll-view class="w100" scroll-y="true" :scroll-into-view="scrollIntoId" :style="{height:scrollHeight}"
  14. @touchmove.stop.prevent>
  15. <view v-if="disdingwei" id="hot">
  16. <!-- 定位模块 -->
  17. <view class="dingwei">
  18. <view class="grey flexa fsmall">
  19. 当前定位
  20. </view>
  21. <view class="blue" @click="back_city({city_name:city})">
  22. {{city?city:'定位失败'}}
  23. </view>
  24. <!-- <view class="dingwei_city">
  25. <view class="bold blue fmiddle" @click="getWarpweft">
  26. <text>{{po_tips}}</text>
  27. </view>
  28. </view> -->
  29. </view>
  30. <!-- 最近模块 -->
  31. <!-- <view class="dingwei" v-if="cacheLocation">
  32. <view class="grey flexa fsmall">
  33. 最近访问
  34. </view>
  35. <view class="dingwei_city dingwei_city_zuijin">
  36. <view class="dingwei_city_one" v-for="(item,index) in cacheLocation" :key="index" @tap="back_city(item)">
  37. {{item.city_name}}
  38. </view>
  39. </view>
  40. </view> -->
  41. <!-- 热门 -->
  42. <!-- <view class="dingwei" v-if="hotCity">
  43. <view class="grey flexa fsmall">
  44. 热门城市
  45. </view>
  46. <view class="dingwei_city dingwei_city_zuijin">
  47. <view class="dingwei_city_one" v-for="(item,index) in hotCity" :key="index" @tap="back_city(item)">
  48. {{item.city_name}}
  49. </view>
  50. </view>
  51. </view> -->
  52. </view>
  53. <!-- 城市列表 -->
  54. <view v-if="searchValue == ''" v-for="(item, index) in list" :id="item.idx" :key="item.idx">
  55. <view class="letter-header bold">{{ item.idx }}</view>
  56. <view class="city-div" v-for="(city, i) in item['cities']" :key="i" @tap="back_city(city)">
  57. <text class="city">{{ city.city_name }}</text>
  58. </view>
  59. </view>
  60. <!-- 搜索结果 -->
  61. <view class="city-div" v-for="(item, index) in searchList" :key="index" @tap="back_city(item)">
  62. <text class="city">{{ item.city_name }}</text>
  63. </view>
  64. <view class="placeholder footer"></view>
  65. </scroll-view>
  66. <!-- 右侧字母 -->
  67. <view class="letters" id="list" v-if="searchValue == ''" @touchstart="touchStart" @touchmove.stop.prevent="touchMove"
  68. @touchend="touchEnd">
  69. <!-- <view class="fmin" @click="scrollTo('hot')">最近</view> -->
  70. <view class="fmin" v-for="item in letter" :key="item.idx">{{ item.idx }}</view>
  71. </view>
  72. <!-- 选中之后字母 -->
  73. <view class="mask" v-if="touchmove">
  74. <view class="mask-r bold">{{scrollIntoId}}</view>
  75. </view>
  76. </view>
  77. </template>
  78. <script>
  79. import Citys from '../../common/index.list.js';
  80. import amapFile from '../../libs/amap-wx.js'
  81. export default {
  82. data() {
  83. return {
  84. amapPlugin: null,
  85. key: 'bb6f4ed802756f963b37c184ce4e9766',
  86. city:'',
  87. statusBar: '0px',
  88. customBar: '45px',
  89. winHeight: 0,
  90. itemHeight: 0,
  91. winOffsetY: 0,
  92. touchmove: false,
  93. scrollHeight: this.statusBarHeight,
  94. ImgUrl: this.ImgUrl,
  95. letter: [],
  96. searchValue: '',
  97. scrollIntoId: '',
  98. list: [],
  99. tId: null,
  100. searchList: [],
  101. showMask: false,
  102. disdingwei: true,
  103. cacheLocation: '', //最近访问
  104. position: '', //定位获取的位置
  105. po_tips: '重新定位',
  106. hotCity: ''
  107. }
  108. },
  109. watch: {
  110. list() {
  111. setTimeout(() => {
  112. this.setList()
  113. }, 100)
  114. }
  115. },
  116. onLoad() {
  117. this.amapPlugin = new amapFile.AMapWX({
  118. key: this.key
  119. });
  120. this.getRegeo()
  121. this.scrollHeight = uni.getSystemInfoSync().windowHeight - parseInt(this.customBar) + 'px'
  122. //获取存储的最近访问
  123. var that = this
  124. uni.getStorage({
  125. key: 'location_key',
  126. success: function(res) {
  127. that.cacheLocation = res.data
  128. }
  129. });
  130. //获取定位 经度纬度
  131. // that.getWarpweft()
  132. // let cityLen = Citys.data.city_nav
  133. this.letter = Citys.index;
  134. this.list = Citys.list;
  135. // this.hotCity = Citys.data.hot_city;
  136. },
  137. methods: {
  138. confirm_city() {
  139. console.log(this.searchValue);
  140. this.$store.commit('getCity', this.searchValue)
  141. uni.redirectTo({
  142. url: '/pages/home/index'
  143. })
  144. },
  145. setList() {
  146. uni.createSelectorQuery()
  147. .in(this)
  148. .select('#list')
  149. .boundingClientRect()
  150. .exec(ret => {
  151. this.winOffsetY = ret[0].top
  152. this.winHeight = ret[0].height
  153. this.itemHeight = this.winHeight / this.list.length
  154. })
  155. },
  156. touchStart(e) {
  157. this.touchmove = true
  158. let pageY = e.touches[0].pageY
  159. let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
  160. if (this.list[index]) {
  161. this.scrollIntoId = this.list[index].idx
  162. }
  163. },
  164. touchMove(e) {
  165. let pageY = e.touches[0].pageY
  166. let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
  167. if (this.list[index] && this.list[index].idx === this.scrollIntoId) {
  168. return false
  169. }
  170. if (this.list[index]) {
  171. this.scrollIntoId = this.list[index].idx
  172. }
  173. },
  174. touchEnd() {
  175. this.touchmove = false
  176. this.touchmoveIndex = -1
  177. },
  178. doneInput() {
  179. uni.hideKeyboard()
  180. },
  181. move(e) {
  182. console.log(111, e);
  183. },
  184. getId(index) {
  185. return this.letter[index];
  186. },
  187. query(source, text) {
  188. let res = [];
  189. var self = this;
  190. let len = source.length
  191. var text = text.toLowerCase()
  192. for (let i = 0; i < len; i++) {
  193. //单字母搜索
  194. if (text.length == 1 && /^[a-zA-Z]$/.test(text)) {
  195. let arr = []
  196. let idx = text.toUpperCase()
  197. if (idx == source[i].idx) {
  198. console.log(222, source[i]);
  199. return source[i].cities
  200. }
  201. }
  202. //其它搜索
  203. if (source[i].cities) {
  204. let _len = source[i].cities.length
  205. for (var n = 0; n < _len; n++) {
  206. let _item = source[i].cities[n]
  207. if (new RegExp('^' + text).test(_item.city_name)) {
  208. res.push(_item);
  209. continue;
  210. }
  211. if (new RegExp('^' + text).test(_item.city_pinyin)) {
  212. res.push(_item);
  213. continue;
  214. }
  215. if (new RegExp('^' + text).test(_item.py)) {
  216. res.push(_item);
  217. continue;
  218. }
  219. }
  220. }
  221. }
  222. return res;
  223. },
  224. isString(obj) {
  225. return typeof obj === 'string';
  226. },
  227. onInput(e) {
  228. const value = e.target.value;
  229. if (value !== '' && this.list) {
  230. const queryData = this.query(this.list, String(value).trim());
  231. this.searchList = queryData;
  232. this.disdingwei = false
  233. } else {
  234. this.searchList = [];
  235. this.disdingwei = true
  236. }
  237. },
  238. back_city(item, hasLocation = false) {
  239. console.log(333, item);
  240. this.$store.commit('getCity', item.city_name)
  241. uni.redirectTo({
  242. url: '/pages/home/index'
  243. })
  244. // if (item) {
  245. // //是否是定位
  246. // if (hasLocation) {
  247. // item = {
  248. // city_name: item.city,
  249. // location: item
  250. // }
  251. // }
  252. // uni.$emit('selectCity', item);
  253. // //unshift 把数据插入到首位,与push相反
  254. // if (!this.cacheLocation) this.cacheLocation = []
  255. // this.cacheLocation.unshift(item)
  256. // this.searchValue = "";
  257. // this.disdingwei = true
  258. // var arr = this.cacheLocation
  259. // //数组去重
  260. // function distinct(arr) {
  261. // let newArr = []
  262. // for (let i = 0; i < arr.length; i++) {
  263. // if (newArr.indexOf(arr[i]) < 0) {
  264. // newArr.push(arr[i])
  265. // }
  266. // }
  267. // return newArr
  268. // }
  269. // this.cacheLocation = distinct(arr).slice(0, 5)
  270. // uni.setStorage({
  271. // key: 'location_key',
  272. // data: this.cacheLocation
  273. // });
  274. // }
  275. // this.back()
  276. },
  277. // 获取定位
  278. getRegeo() {
  279. let _this = this
  280. // uni.showLoading({
  281. // title: '获取定位信息中'
  282. // });
  283. this.amapPlugin.getRegeo({
  284. success: (data) => {
  285. this.city = data[0].regeocodeData.addressComponent.city
  286. // uni.hideLoading();
  287. }
  288. });
  289. }
  290. }
  291. };
  292. </script>
  293. <style scoped>
  294. .fsmall {
  295. font-size: 26rpx;
  296. }
  297. .fmiddle {
  298. font-size: 28rpx;
  299. }
  300. .blue {
  301. color: #007AFF;
  302. }
  303. .bold {
  304. font-weight: 600;
  305. }
  306. .flex {
  307. display: flex;
  308. justify-content: center;
  309. align-items: center;
  310. }
  311. .mask {
  312. position: fixed;
  313. z-index: 3;
  314. top: 40%;
  315. left: 40%;
  316. }
  317. .mask-r {
  318. height: 120rpx;
  319. width: 120rpx;
  320. border-radius: 60rpx;
  321. display: flex;
  322. background: rgba(0, 0, 0, 0.5);
  323. backdrop-filter: blur(5px);
  324. justify-content: center;
  325. align-items: center;
  326. font-size: 40rpx;
  327. color: #FFFFFF
  328. }
  329. .content {
  330. height: 100%;
  331. width: 100%;
  332. background-color: #ffffff;
  333. }
  334. .header {
  335. width: 100%;
  336. position: relative;
  337. z-index: 8;
  338. background-color: #FFFFFF;
  339. }
  340. .back_div {
  341. width: 100rpx;
  342. height: 100%;
  343. display: flex;
  344. justify-content: center;
  345. align-items: center;
  346. }
  347. .back_img {
  348. width: 35rpx;
  349. height: 35rpx;
  350. }
  351. .input {
  352. font-size: 26rpx;
  353. width: 600rpx;
  354. height: 60rpx;
  355. max-height: 60rpx;
  356. border-radius: 10rpx;
  357. background-color: #F5F5F5;
  358. padding-left: 20rpx;
  359. padding-right: 20rpx;
  360. box-sizing: border-box;
  361. }
  362. .title {
  363. font-size: 30rpx;
  364. color: white;
  365. }
  366. .show {
  367. left: 0;
  368. width: 100%;
  369. transition: left 0.3s ease;
  370. }
  371. .hide {
  372. left: 100%;
  373. width: 100%;
  374. transition: left 0.3s ease;
  375. }
  376. .title {
  377. font-size: 30rpx;
  378. color: white;
  379. }
  380. .letters {
  381. position: absolute;
  382. right: 0;
  383. width: 80rpx;
  384. color: #333333;
  385. top: 25%;
  386. text-align: center;
  387. font-size: 24rpx;
  388. font-weight: 510;
  389. }
  390. .letters .fmin {}
  391. .letter-header {
  392. font-size: 28rpx;
  393. padding-left: 40rpx;
  394. box-sizing: border-box;
  395. display: flex;
  396. align-items: center;
  397. }
  398. .city-div {
  399. width: 660rpx;
  400. margin: auto;
  401. padding: 20rpx 0;
  402. border-bottom-width: 0.5rpx;
  403. border-bottom-color: #ebedef;
  404. border-bottom-style: solid;
  405. display: flex;
  406. align-items: center;
  407. }
  408. .city {
  409. font-size: 28rpx;
  410. color: #000000;
  411. padding-left: 30rpx;
  412. }
  413. .dingwei {
  414. width: 90%;
  415. margin: auto;
  416. padding-top: 25rpx;
  417. box-sizing: border-box;
  418. margin-bottom: 26rpx;
  419. }
  420. .dingwei .grey {
  421. margin-bottom: 25rpx;
  422. }
  423. .dingwei_city {
  424. width: 100%;
  425. box-sizing: border-box;
  426. display: flex;
  427. justify-content: space-between;
  428. }
  429. .dingwei_city_one {
  430. height: 60rpx;
  431. background-color: #F5F5F5;
  432. border-radius: 30rpx;
  433. font-size: 26rpx;
  434. padding: 0 20rpx;
  435. display: flex;
  436. justify-content: center;
  437. align-items: center;
  438. margin: 0 20rpx 20rpx 0;
  439. }
  440. .dingweis {
  441. width: 32rpx;
  442. height: 32rpx;
  443. }
  444. .dingwei_city_zuijin {
  445. display: flex;
  446. justify-content: flex-start;
  447. flex-wrap: wrap;
  448. }
  449. </style>