省市区三级联动已无法满足项目需要 故修改选择方式及效果 修改后的效果如下 用到了vant的tabs ![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/64ef73652af64ab263a9c41518fd8d9c.png)
级别可无限增加 支持反向渲染
子集字段children
html
<van-tabs v-model="active" ref="vanTab" color="rgb(30, 136, 245)">
<van-tab :title="item.title" v-for="(item,index) in list" :key="index">
<ul :id="`ul${index}`">
<li v-for="(d,i) in item.data" :key="i" @click="checkItem(d,index)" :class="ids[index]&&ids[index].indexOf(d.id)!==-1?'cur':''">
{{d.shortName}}
<i class="iconfont jiantou" v-if="d.childrenType!=='00'&&d.children && d.children.length>0"></i>
</li>
</ul>
</van-tab>
</van-tabs>
script
data () {
return {
areaName: '',
flattedOrgTree: [], //扁平化处理后的机构数组
areas: [], // 树型机构
areaId: '', // 机构id
list: [], // 联动框内容数组
active: 0,
maxLevel: 1,
ids: [], // 选择机构的id组
arr: [], // 反向渲染暂存的id组
scrollTops: [] // scrollTop组
}
},
初始化
this.$nextTick(() => {
this.list[0] = {
data: this.areas,
title: this.areas[0].name,
id: this.areas[0].id
}
this.ids[0] = this.areas[0].id
this.$forceUpdate()
})
点击展示下级
checkItem (item, n) {
if (item.children && item.children.length > 0) {
this.list.splice(n + 1)
this.list[n].title = item.name
this.list[n].id = item.id
this.list = [...this.list, {
data: item.children,
title: '请选择',
id: ''
}]
this.ids[n] = item.children[0].id
setTimeout(() => {
this.active = n + 1
}, 10)
} else {
// 点击最后一级
this.ids[n] = item.id
this.areaId = item.id
}
},
通过 areaId 反向渲染联动框
// 反查父集id链
reList (id) {
if (id !== '0') {
this.arr.unshift(id)
}
if (this.flattedOrgTree[id] && this.flattedOrgTree[id].parentId && this.flattedOrgTree[this.flattedOrgTree[id].parentId]) {
this.reList(obj, this.flattedOrgTree[id].parentId)
}
},
initPicker () {
this.list[0] = {
data: this.areas,
title: this.areas[0].name,
id: this.areas[0].id
}
this.ids[0] = this.areas[0].id
this.arr = []
this.reList(this.areaId)
if (//areaId不是初级id) {
this.ids = this.arr
if (this.ids.length > 0) {
for (let i = 1; i < this.ids.length; i++) {
const pid = this.flattedOrgTree[this.ids[i]].parentId
const p = this.flattedOrgTree[pid]
let data = [{ ...p, children: [] }, ...p.children]
const format = function (arr) {
if (arr.length < 1) return
arr.forEach(obj => {
if (obj.children && obj.children.length > 0) {
const hasUnshiftArr = obj.children.filter(d => { return d.id === obj.id })
if (hasUnshiftArr.length === 0) {
obj.children.unshift({
...obj,
children: []
})
}
format(obj.children)
}
})
}
format(data)
data = data.map(i => {
if (i.childrenType === '00') {
return {
...i,
children: []
}
} else {
return i
}
})
this.list[i] = {
data: data,
title: this.flattedOrgTree[this.ids[i]].name,
id: this.flattedOrgTree[this.ids[i]].id
}
}
this.active = this.ids.length - 1
}
}
},
通过active获取当前选中标签 控制其居中显示 项目使用了rem item行高设置为0.4rem 反向需计算
watch: {
active (n) {
if (this.list[n] && this.list[n].data && this.list[n].data.length > 0) {
let curIndex = 0
this.list[n].data.forEach((item, index) => {
if (item.id === this.ids[n]) {
curIndex = index
}
})
this.$nextTick(() => {
const screenWidth = document.body.clientWidth
document.getElementById(`ul${n}`).scrollTop = curIndex * 0.4 * screenWidth * 100 / 750
})
}
}
}
}