城市联动组件插件思想分析

前言

笔者今日写了个城市插件,用来实现城市的三级/二级联动。由于现在三大框架异常流行,各种城市组件也是各放异彩, 本文主要在于解析城市组件书写的思想。

实际交互图如下。可以进行点击交互选择省市区,也可以使用全拼或者是首拼进行快速搜索。

          

 常用的处理方式分析

一般来说 设计城市联动/拼音搜索的功能分为两种方式

  1. 后台查询返回;前台传入拼音,后台进行过滤,字符拼接,接口返回。缺点:反应的速度会比较慢。
  2. 前台存储一份省市区数据,全部事情由前台自行处理。缺点:前端会多出一个city_json的大文件。

至于哪种方式好,个人觉得还是第二种完全由前端处理的方式较好。原因如下:

  • 前端可通过懒加载,在用户无感知的情况下进行city数据的加载。
  • 通过防抖截流函数,可以对用户使用拼音搜索时有可能出现的卡顿现象进行良好的优化。
  • 减少了对后台的频繁交互,不用依赖后台。用户体验也会很好。

思想解析

先看一下组件大致的设计思想。

城市组件设计

省市区集合:

provinceJson 省份json

cityJson 城市json

countyJSon 区县json

输出的字符串:

totalStr:形如 安徽-合肥-政务区 的字符串

cityAndCounStr:形如 合肥-政务区 的字符串

listContentJson:只含有城市的json 如:hf [ 合肥 海丰]

数据格式

 {"id":"110000","parentId":"0","level":"1","letter":"BJ","name":"北京","pinyin":"beijing"},{"id":"110100","parentId":"110000","level":"2","letter":"BJ","name":"北京","pinyin":"beijing"},{"id":"110114","parentId":"110100","level":"3","letter":"CPQ","name":"昌平区","pinyin":"changpingqu"},{"id":"120100","parentId":"120000","level":"2","letter":"TJ","name":"天津","pinyin":"tianjin"},{"id":"120115","parentId":"120100","level":"3","letter":"BCQ","name":"宝坻区","pinyin":"baochiqu"},{"id":"130102","parentId":"130100","level":"3","letter":"ZAQ","name":"长安区","pinyin":"changanqu"},{"id":"130230","parentId":"130200","level":"3","letter":"CFDQ","name":"曹妃甸区","pinyin":"caofeidianqu"},{"id":"130304","parentId":"130300","level":"3","letter":"BDHQ","name":"北戴河区","pinyin":"beidaihequ"}

 数据分析

  • 前端存储的数据是经过特殊转化的,将所有的省市区数据混杂在一起,作为平级的对象,以level确定地理级别。parentId作为该城市/县区的上级地理位置。
  • 为了减少过滤出省/市/区的循环,我直接在拿到转化的数据后进行了如下形式的定义:
var province_Json=["省份对象1","省份对象2","省份对象3",...]
var city_Json=["城市对象1","城市对象2","城市对象3",...]
var county_Json=["县区对象1","县区对象2","县区对象3",...]
  • 首拼与全拼 其实一种过滤方式,将大写的首拼/用户输入的字母进行小写转化,再去根据需求,首先匹配cityJson (所有城市的对象数组),然后按照parentId找到省份后拼接字符串。甚至可以再将地理数据进行改造,将首拼与全拼再拼接起来作为一个字符串进行匹配,比如:BJbeijing。
  • 中文的搜索逻辑跟拼音逻辑一致,如下:
 if(value2.letter.toLocaleLowerCase().search(inputVal) > -1 || value2.name.search(inputVal) > -1) {//todo...}

代码实现逻辑

  1. 匹配到对应的城市 (》=15条时 break) 当前城市下的countryName做字符串的拼接 当前城市上对应的省份存下来,并做好字符串的拼接。
  2. 如果小于15条 对countryJson 进行过滤,总数===15时,break ,找到当前的countryJson后,一级一级向上找其对应的城市与省份。
  3. 点击的联动思想也就是找到当前选择的省市进行下级别的搜索渲染。

实际项目中遇到的问题

1:当输入的字符串长度小于3时如何搜索?

  • 答:此时只进行首字母letter的搜索,至于为什么这样设计,是为了防止出现更多的循环,造成页面的卡顿。因为我们的数据还是首字母与全拼分开的。

2:如果所搜索的城市不满足15条,此时需要从区县搜索,但如果这个区县所在的城市与省份已经存在怎么办?

  • 答:对于最后输出的包含totalStr的数组进行去重。

3:刚开始点击输入框 会弹出旧的城市选择组件,其后的交互形式

  • 不输入值,完全使用旧组件,可以正常使用,
  • 选择城市后,减少字符串个数,怎么去避免新组件的查询

每次点击输入框 都可以弹出旧框,当输入框的值变化时 就隐藏掉旧框 显示新框

总结

省市区的联动不难,而且会让你在用寻找下一地理目标时感觉到爽。有时候一些项目实现起来比较难,前端数据处理起来较麻烦时,可以换个角度去思考问题,直接更改原始数据,会让问题变得更好coding。

原文地址:https://www.cnblogs.com/mamimi/p/8032901.html