写在结尾:我的项目的框架是vue+vant,业务需要一个级联的地区抉择,写完才发现vant自身也有这组件....起初看vant自身用的逻辑跟我不太一样,感觉还有点思考价值那就发上来当做实现记录吧~

总体思路(select与tabs独立):

  1. 列表抉择(select)
    1)获取以后tabs的长度 -> 设置以后active的name
    2)通过levelCollect(最终抉择的数据集)设置每个层级,例:['第一层数据','第二层数据','第三层数据',...]
    3)删除后级数据,更新tabs长度
    4)如果有上级,新增active并选中,如果没有设置实现
  2. 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