写在结尾:我的项目的框架是vue+vant,业务需要一个级联的地区抉择,写完才发现vant自身也有这组件....起初看vant自身用的逻辑跟我不太一样,感觉还有点思考价值那就发上来当做实现记录吧~
总体思路(select与tabs独立):
- 列表抉择(select)
1)获取以后tabs的长度 -> 设置以后active的name
2)通过levelCollect(最终抉择的数据集)设置每个层级,例:['第一层数据','第二层数据','第三层数据',...]
3)删除后级数据,更新tabs长度
4)如果有上级,新增active并选中,如果没有设置实现 - tab抉择(tabsClick)
1)拷贝一次原始数据,设置列表筛选数据:0级应用原始数据,其它选用存储数据设置高亮
2)滚动到选中
目前性能反对:
·自定义数据
·N级数据联动
·下级数据抉择后批改
·选择项高亮
todo:
数据回填
效果图:
addressCard.vue
<template> <div class="addressWrapper"> <h4>请抉择所在地区</h4> <div class="tabs"> <van-tabs ref='tabs' v-model="active" scrollspy :ellipsis='false' @click='tabsClick' > <van-tab v-for="(tabItem,i) in tabsData" :title="tabItem.name" :key='i'>.</van-tab> </van-tabs> <div class="content"> <div :class="['item',{select:item.select}]" v-for="(item,j) in areaJson" :key='j' @click='select(item)'> {{item.name}} </div> </div> </div> </div></template><script>import { Tab,Tabs } from 'vant';import areaJson from './areaJson/pcas-code.json'export default { components: { [Tab.name]: Tab, [Tabs.name]:Tabs }, data(){ return{ active:1, levelCollect:[], originArea:areaJson, areaJson, tabsData:[{ name:'请抉择' }] } }, created(){ }, methods:{ select(item){ // 获取以后tabs的长度 let len = this.tabsData.length // 设置以后active的name this.tabsData[this.active].name = item.name // 设置每个层级 this.levelCollect[this.active] = item if(this.active<len){ // 删除后部的城镇 this.tabsData.splice(this.active+1) // 更新tabs长度 len = this.tabsData.length } // 如果有上级,新增active并选中 if(item.children){ this.tabsData.push({name:'请抉择'}) // this.active = len this.$refs.tabs.scrollTo(len) this.areaJson = item.children }else{ this.tabsClick(this.active,item.name) } }, tabsClick(name,title){ // 设置列表筛选数据:0级应用原始数据,其它选用存储数据设置高亮 if(name===0){ this.areaJson = this.originArea.slice().map(item=>{ return { ...item, select:item.name===title } }) }else{ this.areaJson = this.levelCollect[name-1].children.map(item=>{ return { ...item, select:item.name===title } }) } // 滚动到选中 this.$nextTick(()=>{ let doc = document.querySelector('.select') doc&&doc.scrollIntoView(); }) } }};</script><style lang="less" scoped>.addressWrapper { padding:20px 10px; h4{ text-align:center; } .tabs{ margin-top:20px; /deep/.van-tabs__content{ display: none; } .content{ margin-top:20px; height: 200px; overflow: scroll; .item{ line-height:40px; font-size:14px; &.select{ color:red; } } } }}</style>
附上本文中地区pcas-code.json数据:
https://github.com/modood/Administrative-divisions-of-China/blob/master/dist/pcas-code.json