公司上一期項目中新增了省市區滑動三級聯動效果,用的是mint-ui的picker組件和popup組件,效果如下:點擊確定換地區,點擊取消不變
省市區數據是后台給的(根據上一級的id,獲取下一級數據列表,省列表傳0),數據格式如下
接下來就直接上代碼了
引入組件后的html部分
<mt-pop v-model="popupVisible" position="bottom" class="prop-tk"> <div class="clR pop-btn clearfix"> <p @click="cancle">取消</p> <p @click="sureMap">確定</p> </div> <mt-picker ref="pickCom" :slots="slots" @change="onValuesChange" value-key="areaName"></mt-picker> </mt-pop>
data里的slots數據和mint-ui格式一樣
slots:[
{
flex: 1,
defaultIndex: 0,
values:[],
className: 'slot1',
textAlign: 'center',
}, {
pider: true,
content: '-',
// className: 'slot2'
}, {
flex: 1,
values:[],
className: 'slot3',
textAlign: 'center'
}, {
pider: true,
content: '-',
// className: 'slot4'
}, {
flex: 1,
values: [],
className: 'slot5',
textAlign: 'center'
}
],
頁面加載時獲取省市區數據(默認省和市是上個頁面帶過來的)
this.$nextTick(() => {
// 獲取省數據
_this.getPrevenceData(0).then(res=>{
_this.slots[0].values = res;
// 根據默認省獲取要顯示的省
res.forEach((item,index)=>{
// 上個頁面傳過來的省
if(item.areaName == _this.mrProvience){
_this.mrpId = item.id;
_this.slots[0].defaultIndex= index;
// 獲取市數據
var cityList = _this.getPrevenceData(item.id);
// 根據默認市獲取要顯示的市
cityList.then(rescity =>{
// 給數據做緩存取消時用
_this.oldCityList =rescity;
_this.slots[2].values = rescity;
rescity.forEach((item,index)=>{
if(item.areaName == _this.showCity){
// 緩存id如果滑動時id變化才發請求
_this.mrcid = item.id;
_this.slots[2].defaultIndex= index;
// 獲取區的數據
var quList = _this.getPrevenceData(item.id);
quList.then(resqu =>{
_this.oldQuList = resqu;
_this.slots[4].values = resqu;
_this.cityDataReady = true;
var valueArr = this.$refs.pickCom.getValues()
this.oldSlots = valueArr.concat();
})
}
})
})
}
})
})
城市滑動變化觸發picker組件的change事件(id變化才發對應請求,否則會多次發請求)
onValuesChange(picker,values){
//判斷如果省的id變化了,就去請求市和區,否則只請求區
if(this.cityDataReady){
//當省變化的時候,請求市和區
if(this.mrpId != values[0].id){
//請求市
this.getPrevenceData(values[0].id).then(res =>{
picker.setSlotValues(2,res);
this.mrpId = values[0].id;
this.mrcid = values[2].id;
})
}
//當市變化的時候,請求區
if(this.mrcid !=values[2].id){
//請求區,當僅僅是區變化的時候,不需要發任何請求
this.getPrevenceData(values[2].id).then(res =>{
picker.setSlotValues(4,res);
this.mrpId = values[0].id;
this.mrcid = values[2].id;
})
}
}
},
點擊確定緩存當前數據
sureMap(){
this.popupVisible = false;
// 獲取變換后的城市數據
var valueArr = this.$refs.pickCom.getValues()
this.oldSlots = valueArr.concat();
this.oldCityList = this.$refs.pickCom.getSlotValues(2);
this.oldQuList = this.$refs.pickCom.getSlotValues(4)
},
點擊取消時把緩存的數據賦值給picker組件
cancle(){
_this.popupVisible = false;
// 把緩存的數據賦值給對應的slot
_this.$refs.pickCom.setSlotValues(2,_this.oldCityList);
_this.$refs.pickCom.setSlotValues(4,_this.oldQuList);
_this.$refs.pickCom.setValues(this.oldSlots);
}
在做這個功能時出現的問題主要有2個,一個是change時多發請求問題,第二個就是取消時還要回到原來的數據(因為組件默認change之后自動就變了)
還好后來問題都解決了