H5W3
当前位置:H5W3 > JavaScript > 正文

【JS】vue+vant移动端地区级联选择组件

vue+vant移动端地区级联选择组件

quanta发布于 今天 08:25

写在开头:项目的框架是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:
数据回填

效果图:
【JS】vue+vant移动端地区级联选择组件
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

javascriptvue.jscascadervant
阅读 88更新于 今天 08:32
本作品系原创,采用《署名-非商业性使用-禁止演绎 4.0 国际》许可协议
avatar

quanta

no bug

11 声望
2 粉丝

0 条评论
得票时间

avatar

quanta

no bug

11 声望
2 粉丝

宣传栏

写在开头:项目的框架是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:
数据回填

效果图:
【JS】vue+vant移动端地区级联选择组件
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

本文地址:H5W3 » 【JS】vue+vant移动端地区级联选择组件

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址