接到过一个城市级联选择的需求,要求将中国大陆内的所有城市以列表的形式返回给前端,但只定义一个cityLevel的key用于标记该城市为几线城市,且需要实现根据任意城市选择或根据城市等级选择,还要包含全选和反选功能。初看其实需求并不复杂,但其实坑点非常多,尤其在使用了Element Plus中的el-cascader这个组件来实现的时候,遇到了包括勾选的城市及省的联动关系、数据结构转换、全选反选部分情况下视图不更新等问题。所以大致做一下记录,这个问题解决后的收获还是挺多的。

template的模板如下


填充的初始数据结构如下,也就是后端初始返回的数据结构(原本是希望后端根据前端需求返回正确且方便的数据结构的,但该需求新来的菜b后端同事似乎并不是很清楚)


首先要实现在勾选某个省下所有城市的时候,右侧展示区域只展示这个省的信息;反之则展示已经勾选的所有城市。这里其实挺简单,只需要考虑数组去重及组件的v-model数据同步问题,简单实现如下:


大致思路其实是先把某个省下的所有事的id筛选出来,然后定义一个allSelected布尔值,标记这个省下的所有市是否全选了,如果已经全选,则加这个省加入到newData数组;反之则加入这些所有市的id,再将newData赋值给selectedData进行响应式视图更新。ok,第一个小点完成,相比之后遇到的坑,这个点算是一个很顺利的实现。接下来遇到了第一个棘手的问题。

观察如下代码:


上述代码其实是勾选的城市进行反选的功能,首先将整个数组进行展平(selectedCityIds为二维数组),然后通过filter求差集的操作,看似已经实现了功能,但多在视图上点击几次就发现有时勾选状态会有一个短暂的freezing状态,也就是控制台有数据变化,但已勾选的城市并未变化。为什么视图会不更新呢?这个问题我想后面单独写一篇文章来描述,先说临时的解决办法(使用了条件渲染指令v-if来销毁dom后重新渲染),这个方法显然并不是一个好方法,一点也不优雅。

。。。