vant中的Cascader級聯選擇異步加載地區(qū)數據方式
更新時間:2024年07月02日 08:36:59 作者:Fighting寧
這篇文章主要介紹了vant中的Cascader級聯選擇異步加載地區(qū)數據方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
使用vant的Cascader級聯選擇異步加載地區(qū)數據
需求
因為全國地區(qū)數據太多,如果要一次加載出來,再顯示頁面會比較慢。所以通過接口點擊獲取當前的數據
需要注意的點
- 后臺接口在返回數據時,如果有下一級的數據,要讓后臺返回children,如果不返回,控件就會出現關閉彈框無法點擊下一級的bug(控件是根據是否有children來判斷是否要繼續(xù)點擊的,前端是無法知道是否存在下一級數據的)
- 添加數據的3種方案任選一種就可以,推薦第一種,無論多少層級都可以添加上。第二種只判斷了4級的添加,5級數據添加不上,第三種是遞歸的方式添加數據
<van-cascader v-model="cascaderValue" title="請選擇所在地區(qū)" :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: '', // 地區(qū)的id
divisionNames: '', // 地區(qū)的名字
}
},
第一種方案
比較簡單,vant中觸發(fā)本身的change事件,可以拿到當前點擊的元素,以及它的上層元素,我們只需要把請求到的最新數據,加在最里面的數據結構中即可
methods: {
// 級聯數據全部選項選擇完畢后,會觸發(fā) 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數據
// 拿到數據后,動態(tài)添加
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: {
// 級聯數據全部選項選擇完畢后,會觸發(fā) 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數據
// 拿到數據后,動態(tài)添加
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 // 城市下的城區(qū)
let index = areas.findIndex(item => item.id === value) // 城區(qū) index
areas[index].children = res.data
// this.$set(this.options[firstIndex].children[secondIndex].children[index], 'children', res.data)
}
})
},
}
第三種方案
// 級聯數據全部選項選擇完畢后,會觸發(fā) 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數據
// 拿到數據后,動態(tài)添加
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)
}
}
- 第一次獲取到的數據

- 點擊山東省后獲取的數據

總結
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
vscode vue3中jsconfig與tsconfig的區(qū)別詳細講解
這篇文章主要介紹了vscode vue3中jsconfig與tsconfig區(qū)別的相關資料,jsconfig.json用于JavaScript項目,允許處理JS文件,tsconfig.json用于TypeScript項目,控制編譯選項,文中通過代碼介紹的非常詳細,需要的朋友可以參考下2025-05-05
Vue?通過this.$emit()方法子組件向父組件傳值(步驟分享)
這篇文章主要介紹了Vue?this.$emit()方法通過子組件向父組件傳值,第一步在父組件中引入子組件,第二步子組件向父組件傳值,本文通過需要的朋友可以參考下2022-11-11
Vue Element前端應用開發(fā)之組織機構和角色管理
本篇文章繼續(xù)深化Vue Element權限管理模塊管理的內容,介紹組織機構和角色管理模塊的處理,使得我們了解界面組件化模塊的開發(fā)思路和做法,提高我們界面設計的技巧,并減少代碼的復雜性,提高界面代碼的可讀性,同時也是利用組件的復用管理。2021-05-05
Vue中@click.stop與@click.prevent、@click.native使用
這篇文章主要介紹了Vue中@click.stop與@click.prevent、@click.native使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-08-08

