vant中的Cascader 级联选择异步加载地区数据
vant中的Cascader 级联选择异步加载地区数据。
·
- 背景:使用vant的Cascader 级联选择异步加载地区数据
- 需求:因为全国地区数据太多,如果要一次加载出来,再显示页面会比较慢。所以通过接口点击获取当前的数据
- 需要注意的点
- 后台接口在返回数据时,如果有下一级的数据,要让后台返回children,如果不返回,控件就会出现关闭弹框无法点击下一级的bug(控件是根据是否有children来判断是否要继续点击的,前端是无法知道是否存在下一级数据的)
- 添加数据的3种方案任选一种就可以,推荐第一种,无论多少层级都可以添加上。第二种只判断了4级的添加,5级数据添加不上,第三种是递归的方式添加数据
<van-cascader v-model="cascaderValue" title="请选择所在地区" :options="options" @close="areaShow = false" @finish="onFinish" :field-names="fieldNames" @change="onChangeArea" />
- 需要用到的data中的变量
export default {
data() {
return {
areaShow: false,
cascaderValue: '',
fieldNames: {
text: 'name',
value: 'id',
children: 'children'
},
// 选项列表,children 代表子选项,支持多级嵌套
options: [],
divisionIds: '', // 地区的id
divisionNames: '', // 地区的名字
}
},
- 第一种方案:比较简单,vant中触发本身的change事件,可以拿到当前点击的元素,以及它的上层元素,我们只需要把请求到的最新数据,加在最里面的数据结构中即可
methods: {
// 级联数据全部选项选择完毕后,会触发 finish 事件
onFinish({ selectedOptions }) {
this.divisionNames = selectedOptions.map(option => option.name).join('/')
this.divisionIds = selectedOptions.map(option => option.id).join(',')
this.areaShow = false
},
// 从接口请求获取第一层的数据,---比如北京
async getAreaList() {
let id = ''
let res = await getAreaList(id)
res.data.forEach(item => {
this.options.push({
name: item.name,
id: item.id,
children: item.children || null// 这个很关键
})
})
},
onChangeArea({ value, selectedOptions, tabIndex }) {
// 需要后台接口返回children数据
// 拿到数据后,动态添加
getAreaList(value).then(res => {
// 第一种方案
this.addTree(selectedOptions, res.data, value)
})
},
addTree(selectedOptions, children, id) {
selectedOptions.forEach(item => {
if (item.id === id) {
item.children = children
}
})
}
}
}
- 第二种方案:不推荐
methods: {
// 级联数据全部选项选择完毕后,会触发 finish 事件
onFinish({ selectedOptions }) {
this.divisionNames = selectedOptions.map(option => option.name).join('/')
this.divisionIds = selectedOptions.map(option => option.id).join(',')
this.areaShow = false
},
// 从接口请求获取第一层的数据,---比如北京
async getAreaList() {
let id = ''
let res = await getAreaList(id)
res.data.forEach(item => {
this.options.push({
name: item.name,
id: item.id,
children: item.children || null// 这个很关键
})
})
},
onChangeArea({ value, selectedOptions, tabIndex }) {
// 需要后台接口返回children数据
// 拿到数据后,动态添加
getAreaList(value).then(res => {
// 第二种方案
if (tabIndex === 0) {
let index = this.options.findIndex(item => item.id === value)
this.options[index].children = res.data
// this.$set(this.options[index], 'children', res.data)
} else if (tabIndex === 1) {
let firstIndex = this.options.findIndex(item => item.id === selectedOptions[0].id) // 省级 index
let cities = this.options[firstIndex].children // 所有城市
let index = cities.findIndex(item => item.id === value) // 市级 index
cities[index].children = res.data
// this.$set(this.options[firstIndex].children[index], 'children', res.data)
} else if (tabIndex === 2) {
let firstIndex = this.options.findIndex(item => item.id === selectedOptions[0].id) // 省级 index
let cities = this.options[firstIndex].children // 所有城市
let secondIndex = cities.findIndex(item => item.id === selectedOptions[1].id) // 市级 index
let areas = cities[secondIndex].children // 城市下的城区
let index = areas.findIndex(item => item.id === value) // 城区 index
areas[index].children = res.data
// this.$set(this.options[firstIndex].children[secondIndex].children[index], 'children', res.data)
}
})
},
}
``
- 第三种方案
// 级联数据全部选项选择完毕后,会触发 finish 事件
onFinish({ selectedOptions }) {
this.divisionNames = selectedOptions.map(option => option.name).join('/')
this.divisionIds = selectedOptions.map(option => option.id).join(',')
this.areaShow = false
},
// 从接口请求获取第一层的数据,---比如北京
async getAreaList() {
let id = ''
let res = await getAreaList(id)
res.data.forEach(item => {
this.options.push({
name: item.name,
id: item.id,
children: item.children || null// 这个很关键
})
})
},
onChangeArea({ value, selectedOptions, tabIndex }) {
// 需要后台接口返回children数据
// 拿到数据后,动态添加
getAreaList(value).then(res => {
// 第三种方案
this.addTree1(res.data, value)
})
},
// 递归写法
addTree1(list, value) {
function addTree2(json, id) {
const index = json.findIndex(ev => ev.id == id)
if (index > -1) {
json[index].children = list
return
} else {
json.map(item => {
if (item.children) {
addTree2(item.children || [], value)
}
})
}
}
addTree2(this.options, value)
}
}
- 第一次获取到的数据
- 点击山东省后获取的数据
更多推荐
已为社区贡献6条内容
所有评论(0)