城市选择器应该是比较常用的一个组件,用户可以去选择自己的城市,选择城市后返回,又根据自己选择的城市搜索小区。

功能展示

这是选择结果

这是选择城市

这是搜索小区

这是搜索小区接口,key为城市名字,id是城市的id

假如切换城市

搜索接口也会相应变化,id=0997 就是指定的搜索城市id

技术栈

vue2.0+vue-router+webpack+vuex+less+better-scroll+axios

webpack
resolve: {extensions: ['.js', '.vue', '.json'],alias: {'vue$': 'vue/dist/vue.esm.js','src': resolve('src'),'common' : resolve('src/common'),'components': resolve('src/components'),'base': resolve('src/base'),"api":resolve('src/api')}},

用less需要引入less和less-loader,但是不需要在webpack操作,webpack已经操作好了

技术栈介绍

所有城市是本地维护的,在city.js中

1、axios封装

import {ajaxUrl} from "./config"
import axios from 'axios'export function getSearchData(key,id){var obj = {op:"search",key,id}return axios.get(ajaxUrl.searcUrl,{params: obj}).then((res)=>{return Promise.resolve(res.data);}).catch((err)=>{return Promise.resolve(err);})
}

2、axios调用,因为目前没有接口,所以只是模拟演示接口,但不影响逻辑

import {getSearchData} from "api/search"
_getDiscList(key,id){this.searchList=["八方城","西溪北苑北区","西溪北苑西区","西溪北苑东区","万科城","恒大城","西溪科技园","未来科技城","智慧城","春天家园","茶张新苑","双水磨小区","小区1","小区2","小区3","小区4","小区5","小区6","小区7"];getSearchData(key,id).then((res)=>{},(err)=>{})},

3、vuex状态管理,vuex我就不介绍了,具体可以去看官网

4、主要介绍一下state中变量的含义

import {initial} from "common/js/config"
const state = {selectCity:initial.city,selectCommunity:initial.community,hasSelCityID:-1
}
export default state

5、config.js

export const initial = {city:"杭州",community:"八方城"
}

selectCity是选择的城市

selectCommunity是选择的小区

hasSelCityID是选择城市的id,根据此id选择对应小区

6、better-scroll

better-scroll 是之前封装好的一个页面滚动组件

7、vue-router

8、页面滑动对应title也变化原理

首先需要记住变量scrollY,这是记录页面滚动到哪个title

data(){return{city:[],scrollY: -1,currentIndex:0,diff:-1,}},

初始化的时候初始化这三个变量,probetype=3是better-scroll可支持touchmove事件的参数

created(){this.touch = {};this.listenScroll = true;this.listenHeight = [];this.probetype = 3;},

时刻计算高度,并检测页面滚动到哪个位置

watch:{city(){setTimeout(()=>{this._calculateHeight()},20)},scrollY(newY){// 滚动到中间部分const listenHeight = this.listenHeight;// 滚动到头部以上if (newY>=-25) {this.currentIndex = 0;return;}for(let i=0;i<listenHeight.length-1;i++){let height1 = listenHeight[i];let height2 = listenHeight[i+1];// 如果没在下限,且在height1和height2之间if (-newY>=height1 && -newY<=height2) {this.currentIndex = i;this.diff = height2 + newY;return;}}},diff(newVal){let fixedTop = (newVal>0 && newVal<TITLE_HEIGHT)?newVal-TITLE_HEIGHT:0;if (this.fixedTop === fixedTop) {return}this.fixedTop = fixedTop;this.$refs.fixed.style.transform = `translate3d(0,${fixedTop}px,0)`}}

_calculateHeight(){this.listenHeight = [];const list = this.$refs.listGroup;let height = 0;this.listenHeight.push(height);for(let i =0;i<list.length;i++){let item = list[i];height +=item.clientHeight;this.listenHeight.push(height);}},

滚动指定位置

    _scrollTo(index){if (!index && index!=0) {return}// 点击右边字母跳到指定位置并高亮this.scrollY = -this.listenHeight[index]-1;this.$refs.cityList.scrollToElement(this.$refs.listGroup[index],0);},

改变标题

fixedTitle(){if (this.scrollY>0) {return ""}return this.city[this.currentIndex]?this.city[this.currentIndex].initial:""}

点击字右边索引跳转指定位置

onShortcutTouchStart(e){let anchorIndex = getData(e.target,'index');console.log(anchorIndex);let firstTouch = e.touches[0];this.touch.y1 = firstTouch.pageY;this.touch.anchorIndex = anchorIndex;// this.$refs.singerlist.scrollToElement(this.$refs.listGroup[anchorIndex],0);this._scrollTo(anchorIndex)},

9、搜索组件

搜索输入框是一个组件,组件负责监听input的model变化,只要变化就派发事件,引用该组件的组件,只需要监听派发的事件即可

created(){this.$watch('query',(newQuery)=>{this.$emit('query',newQuery)})}

11、城市搜索,支持首字母(不区分大小写)搜索

首先给城市加首字母

_addFirstLetter(citylist){for(var i=0;i<citylist.length;i++){for(var j=0;j<citylist[i].list.length;j++){citylist[i].list[j]['firstLetter'] = citylist[i].initial;}}this._formatCityList(citylist);},

序列化数组

// 序列化数组
    _formatCityList(arr){var letterArr = {};for (var i = 0; i < arr.length; i++) {if (!(arr[i]['initial'] in letterArr)) {letterArr[arr[i]['initial']] = [];for(var j=0;j<arr[i].list.length;j++){letterArr[arr[i]['initial']].push(arr[i].list[j]);}}else{for(var j=0;j<arr[i].list.length;j++){letterArr[arr[i]['initial']].push(arr[i].list[j]);}}}this.letterList = letterArr;},

搜索

正则 var reg = new RegExp(newVal == '' ? 'xxyy' :newVal, 'ig');   ig是不区分大小写

// 搜索
    _search(newVal){var reg = new RegExp(newVal == '' ? 'xxyy' :newVal, 'ig');var _arr = [];for(var i in this.letterList){for(var j = 0; j < this.letterList[i].length; j++){if(reg.test(this.letterList[i][j]['name']) ||reg.test(this.letterList[i][j]['firstLetter'])){_arr.push(this.letterList[i][j]);}}}this.searchList = _arr;},

因为引入的搜索框组件,所以只需要监听input内容改变后派发的事件即可

 this._search(newVal);this.queryCity = newVal;

data 搜索结果会放在searchList里面,只需要v-for即可,但是需要边缘处理,没有搜索结果,有一个UI上的一个展示

data(){return{city:[],letterList:[],searchList: [], //搜索结果queryCity:"",placeholder:"输入城市名称"}},

10、每次点击搜索城市后触发mutation,修改state

selectItem(item){this.afterSelect(item)},selectSearchItem(item){this.afterSelect(item)},// 选择之后的操作
    afterSelect(item){this.$router.back();this.setCity(item.name);this.setCityId(item.zip);},...mapMutations({setCity:"SET_CITY",setCityId:"SET_CITYID"})

推荐使用vuex钩子,具体如何使用可去看官网

import {mapMutations} from "vuex"
import {mapGetters} from "vuex"

业务功能模板

1、select.vue

<template lang="html">
<!-- <transition name="slide"> --><div><div @click="city" class="city clearfix"><i>所在城市</i><em></em><span>{{selCity}}</span></div><div @click="community" class="community clearfix"><i>小区名称</i><em></em><span>{{selCommunity}}</span></div></div>
<!-- </transition> -->
</template>

2、city.vue

<transition name="slide"><div class="xin-widget-citys animated"><SearchBox class="search" @query="query" :placeholder="placeholder"></SearchBox><div class="currentCity" v-if="queryCity===''"><ul><h2>当前定位城市</h2><li>杭州</li></ul></div><Scroll :data="searchList" class="searchlist" v-if="queryCity !== ''" :class="{'bg':searchList.length === 0}"><div><ul v-if="searchList.length!==0"><li class="bdb" v-for="item in searchList" @click="selectSearchItem(item)">{{item.name}}</li></ul><img v-else src="../../common/img/404.png" class="nomatch"/></div></Scroll><CityList class="city" v-if="queryCity===''" @selectItem="selectItem"></CityList></div>
</transition>

3、search.vue

<transition name="slide"><div class="xin-widget-citys animated"><SearchBox class="search" @query="query" :placeholder="placeholder"></SearchBox><Scroll :data="searchList" class="searchlist" v-if="queryCity !== ''" :class="{'bg':searchList.length === 0}"><div><ul v-if="searchList.length!==0"><li v-for="item in searchList" @click="selectSearchItem(item)">{{item}}</li></ul><img v-else src="../../common/img/404.png" class="nomatch"/></div></Scroll></div></transition>

基础组件模板

1、city-list.vue

<Scroll class="citylist" :data="city" ref="cityList" :listenScroll="listenScroll" @scroll="scroll" :probetype="probetype"><div><div v-for="(item,index) in city" class="allCity" ref="listGroup"><h2>{{item.initial}}</h2><ul><li v-for="city in item.list" @click="selectItem(city)">{{city.name}}</li></ul></div></div><div class="list-shortcut" @touchstart="onShortcutTouchStart"><ul><li class="starCity"></li><li v-for="(item,index) in city" class="item"  :data-index="index">{{item.initial}}</li></ul></div><div class="list-fixed" v-show="fixedTitle" ref="fixed"><h1 class="fixed-title">{{fixedTitle}}</h1></div></Scroll>

2、search-box.vue

<template><div class="search-box"><i class="icon-search"></i><input ref="query"  class="box" :placeholder="placeholder" v-model="query"/></div>
</template>

总结

以上就是城市选择器的大概介绍,源码我已经放在了我的github上了,有需要可去下载,如果有帮助,麻烦给个star,鼓励我继续努力,谢谢!

代码地址:https://github.com/dirkhe1051931999/writeBlog

转载于:https://www.cnblogs.com/dirkhe/p/9573352.html

vue | 基于vue的城市选择器和搜索城市对应的小区相关推荐

  1. vue基于element-ui的Select选择器实现的动态多级联动下拉选择

    本文讲的是 vue基于 element-ui 的 Select选择器 实现的动态多级联动下拉选择 基于原生select标签实现请看我的另外一篇文章 vue实现动态多级联动选择 本文demo地址 代码如 ...

  2. 怎么把HTML网页重构为VUE,基于vue cli重构多页面脚手架过程详解

    官方提供的项目生成工具vue-cli没有对多页面webApp的支持,但是在实际的项目中,我们需要这样的脚手架,参考了很多大牛的方法,这里提供了一种我的单页面脚手架转换为多页面脚手架的方案,供大家参考. ...

  3. iOS城市选择器-包含搜索功能

    使用方法 拖入FJChooseCity到项目中,导入 #import"ChooseCityViewController.h"/*** 选中城市后的回调*/ @property (s ...

  4. 基于Vue全家桶制作的的高仿美团APP

    美团外卖APP ? 项目演示地址:http://39.108.232.27:9000 ? GitHub:github.com/bxm0927/vue- 基于 Vue 全家桶 (2.x) 制作的美团外卖 ...

  5. android百度地图定位、城市列表选择搜索

    百度地图的集成在百度地图的开发文档中有详细的介绍:Android定位SDK  | 百度地图API SDK 本文介绍的主要功能有: kotlin语言搭建的项目 百度地图的定位 选择城市(包括省市县三级搜 ...

  6. 基于Vue和Element-UI自定义分组以及分组全选Select 选择器

    文章目录 基于Vue和Element-UI自定义分组以及分组全选Select 选择器 在这里插入图片描述 源代码 基于Vue和Element-UI自定义分组以及分组全选Select 选择器 上一篇博文 ...

  7. 基于vue的颜色选择器vue-color-picker

    项目中有用到颜色选择器的童鞋们可以看过来了 关于color-picker的jquery的插件是有蛮多,不过vue组件没有吧,反正我没有找到, 虽然element-ui里面有这个,但是你愿意为了一个小功 ...

  8. 七十一、Vue项目城市选择页搜索逻辑实现,边输入边搜索功能的解决办法:节流函数

    2020/10/30. 周五.今天又是奋斗的一天. @Author:Runsen 写在前面:我是「Runsen」,热爱技术.热爱开源.热爱编程.技术是开源的.知识是共享的.大四弃算法转前端,需要每天的 ...

  9. js时间选择器_Vuestic Admin一款免费与美妙基于Vue.js开发的管理模板

    Vuestic Admin 简介 vuestic admin是一款流行,免费与美妙的基于Vue.js开发出来的管理模板,包括38以上个定制用户界面组件,由Epicmax开发,由Vasili Savit ...

最新文章

  1. designer.cs 删除后怎么恢复?(复制aspx修改名字后重新生成页面)
  2. JAVA判断输入日期是否合法
  3. JavaScript数组方法map
  4. cmd窗口pip显示不是内部或外部命令,也不是可运行的程序或批处理文件
  5. 30岁从零学计算机,30岁从零学阅读方法来得及吗?
  6. java nat 端口转发_NAT网络地址转换——静态NAT,端口映射(实操!!)
  7. php小论坛开发总结,PHP开发 小型论坛教程之添加论坛-2
  8. php的关系数据库,php – 从关系数据库到非关系数据库的数据规范化的最佳实践...
  9. 如何用python获得实时股票信息_【python】用命令行获取实时股票信息
  10. 最小生成树的普里姆算法c实现
  11. 计算机毕业设计之答辩
  12. matlab z统计量,z统计量(z统计量与t统计量)
  13. iPhoneXS、XS Max与iPhoneXR 适配
  14. 如何使用Zend Expressive建立NASA照片库
  15. 干货 | 一起聊聊技术与写作
  16. 邮件发送错了怎么办?TOM VIP邮箱如何撤回邮件
  17. ubuntu64 使用gcc -m32编译成32bit程序
  18. 中医知识分享之《养生十八伤》
  19. 获取淘宝价格区间l-r的商品a的详细信息(商品名等)
  20. 中国农产品流通市场运营状况与发展前景预测报告2022-2027年

热门文章

  1. java聊天室源工程文件_socket实现java聊天室,公告等功能,前后端分离(附源码)...
  2. 语音包mp3_目标明确,为运动而造 ,自带MP3功能的南卡RUNNER PRO骨传导耳机
  3. linux邮件收发程序流程图,[源码和文档分享]基于C语言和TCP Socket实现的Linux环境下的邮件收发客户端程序...
  4. lua游戏脚本实例源码_Redis Lua脚本中学教程(上)
  5. 2018年c++B:换零钞;激光样式(递归法和暴力破解)
  6. 图像识别讲解 以一个简单的图像识别任务为例
  7. kong 网关教程入门
  8. smooth_l1_loss(y_true, y_pred)
  9. 贺利坚老师汇编课程54笔记:CF进位标志CARRY FLAG
  10. 8086的总线操作顺序