test.vue 9.9 KB

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