關於小程式的自定義三級聯動與vant組建的三級聯動,以及四級聯動
最近的專案要求是地址選擇器是自定義的地址,不能直接用全國的地址。由於小程式提供的picker組建是它內部提供的,並沒有提供替換的資料的介面,遂用小程式提供的多列選擇器
後臺獲取的資料結構是這樣的{
“level”: “success”,
“message”: “獲取成功”,
“data”: [
{
“name”: “廣東省”,
“cityList”: [
{
“name”: “廣州市”,
“areaList”: [
{
“name”: “海珠區”,
“townList”: [
“康樂村”,
“瑞寶”,
“鷺江”,
“上衝”,
“大塘”,
“七星崗”,
“後滘”
]
},
{
“name”: “天河區”,
“townList”: [
“土華”,
“東圃”,
“吉山”,
“龍崗村”
]
},
{
“name”: “白雲區”,
“townList”: [
“大埔”,
“新市”,
“棠溪”
]
},
{
“name”: “番禺區”,
“townList”: [
“塘步西”,
“塘步東”,
“植村”,
“南村”,
“大石”,
“沙湧”
]
},
{
“name”: “增城區”,
“townList”: [
“新塘”
]
}
]
},
{
“name”: “東莞市”,
“areaList”: [
{
“name”: “”,
“townList”: [
“鎮口”,
“大朗”
]
}
]
},
{
“name”: “深圳市”,
“areaList”: [
{
“name”: “鹽田區”,
“townList”: [
“沙頭角”
]
},
{
“name”: “寶安區”,
“townList”: [
“大浪”
]
},
{
“name”: “龍崗區”,
“townList”: [
“布吉”,
“橫崗”,
“平湖”,
“阪田”
]
},
{
“name”: “福田區”,
“townList”: [
“八卦嶺”
]
}
]
},
{
“name”: “汕頭市”,
“areaList”: [
{
“name”: “龍湖區”,
“townList”: [
“龍湖工業區”
]
},
{
“name”: “潮陽區”,
“townList”: [
“谷饒”
]
},
{
“name”: “潮南區”,
“townList”: [
“峽山”,
“司馬浦”,
“兩英”,
“陳店”,
“成田”
]
},
{
“name”: “澄海區”,
“townList”: [
“隆都”
]
}
]
}
]
},
{
“name”: “湖北省”,
“cityList”: [
{
“name”: “武漢市”,
“areaList”: [
{
“name”: “礄口區”,
“townList”: [
“漢正街”,
“武勝路”,
“長豐鄉”,
“常碼頭”
]
},
{
“name”: “漢陽區”,
“townList”: [
“快活嶺”,
“磨山工業園”
]
},
{
“name”: “江漢區”,
“townList”: [
“經濟開發區”
]
},
{
“name”: “江岸區”,
“townList”: [
“石橋”
]
}
]
}
]
},
{
“name”: “湖南省”,
“cityList”: [
{
“name”: “株洲市”,
“areaList”: [
{
“name”: “蘆淞區”,
“townList”: [
“龍泉路”,
“董家段高科園”
]
},
{
“name”: “荷塘區”,
“townList”: [
“合泰”
]
}
]
}
]
},
}
實現思路有:
province,一個array存放各種省份[‘廣東省’,‘北京市’]
cityList,一個objcet,存放省份對應的市{‘廣東省’:[‘廣州市’,‘深圳市’],‘北京市’:[‘北京市’,‘什麼市’]}
countyList,一個object,存放市對應的區{‘廣州市’:[‘番禺區’,‘增城區’]};
multiArray3: [[], [], []],小程式傳進的多列聯動的資料格式。分別對應每一列的選項。它這樣設計是不能聯動的。我想到的方法是每當一項改變,動態改變其他列的資料,來實現聯動。
multiIndex3: [0,0,0] 小程式中用來確認選中時,顯示的選項的下標。(點選確認時,必須改變為multiIndex3,從而使它顯示出來,否則點選確認也無法顯示相應值)
程式碼如下
export const mixin1={//用了vue的mixin便於其他頁面也能複用 data(){return{ province:'',//存放省的陣列如:['廣東省','湖南省',````],arr型別 cityList:'',//放某省內的市如:{'廣東省':['廣州市','深圳市'],'北京市':['北京市','什麼市']},obj型別 countyList:'',//{'廣州市':['番禺區','增城區']}放某區市的區 multiArray3: [[], [], []],//這裡multiArray3是傳進多列picker的陣列 multiIndex3: [0,0,0],//這裡必須吐槽一下小程式的設計,我不懂為什麼選擇後,還要自主來更改選中項的index才行。就應該在選中時,內部自動更改相應index就好了。 }}, methods:{ bindMultiPickerColumnChange(e){ let val=e.target.value;//每一項改變時,小程式組建傳來的當列選中項的index switch (e.target.column) { case 0://第一列改變時 let arr=this.getArr(this.province[val],this.cityList) this.$set(this.multiArray3,1,[])//先清空multiArray3的第1項(其實這一步沒必要,只是為了邏輯的完整) this.$set(this.multiArray3,1,arr);//設定第二列資料 let arr2=this.getArr(arr[0],this.countyList);//從第二列拿出第一項中,在countyList中查詢並設定第三列的陣列。這麼做時為了在選擇第一列時,第二列也相應顯示出了相應的市,並且第三列聯動預設有顯示 if(arr2){ this.$set(this.multiArray3,2,arr2);//設定第三組資料 }else{ this.$set(this.multiArray3,2,['-']); } this.$set(this.multiIndex3,0,val);//設定當前顯示的下標 this.$set(this.multiIndex3,1,0); this.$set(this.multiIndex3,2,0);//又來吐槽一下小程式,真是糟糕的設計 break; case 1: let arr3=this.getArr(this.multiArray3[1][val],this.countyList); this.$set(this.multiArray3,2,[]) if(arr3){ this.$set(this.multiArray3,2,arr3) }else{ this.$set(this.multiArray3,2,['-']); } this.$set(this.multiIndex3,1,val) this.$set(this.multiIndex3,2,0); break; } }, getArr(address,arr){//返回一個選中項後,對應的下級陣列,例如,選中了廣東省,那麼就從this.cityList中找出key為廣東省的value :['廣州市','深圳市'] for(let p in arr){ if(address==p){ return arr[p] } } }, async getAddress(){//獲取傳入的資料 let res=await this.$request.getData('/other/get-address-all'); this.initAddress=res let province=[];//['廣東省','廣西省','湖南省'] let cityList={};//{'廣東省':['廣州市','深圳市']}放某省內的市 let countyList={};//{'廣州市':['番禺區','增城區']}放某區市的區 if(res.data.level=='success'){//獲取自主傳入的地址 res.data.data.forEach((val)=>{ if(val.name!=''){ province.push(val.name); if(val.cityList!=''){ let arr=[]; val.cityList.forEach(val1=>{ arr.push(val1.name); if(val1.areaList!=''){ let arr2=[] val1.areaList.forEach(val2=>{ arr2.push(val2.name) }) countyList[val1.name]=arr2 } }) cityList[val.name]=arr; } } }) } this.province=province; this.cityList=cityList; this.countyList=countyList; this.multiArray3[0]=this.province this.multiArray3[1]=this.getArr(this.province[0],this.cityList); this.multiArray3[2]=this.getArr(this.multiArray3[1][0],this.countyList); } }, mounted() { this.getAddress() }, }
吃飯了再碼vant的3級聯動
——————————————————分界線————————————————
本處的vant組建用於h5的開發
對於元件vant的話。vant的地址選擇器 詳見 https://youzan.github.io/vant/#/zh-CN/area
本人嘗試用vant提供的多列選擇器,但是從官網上只能找到2列選擇器的相關。對於3列或以上的並沒有提供相應的資料格式。
遂從它的地址選擇器進行入手。
初始化很簡單
傳進一個地址的json檔案即可
(官網有完整的全國地址json)
{
province_list: {
110000: ‘北京市’,
120000: ‘天津市’
},
city_list: {
110100: ‘北京市’,
110200: ‘縣’,
120100: ‘天津市’,
120200: ‘縣’
},
county_list: {
110101: ‘東城區’,
110102: ‘西城區’,
110105: ‘朝陽區’,
110106: ‘豐臺區’
120101: ‘和平區’,
120102: ‘河東區’,
120103: ‘河西區’,
120104: ‘南開區’,
120105: ‘河北區’,
// …
}
}
因為業務要求時自定義的地址。遂對獲取下來的data進行重組資料。資料結構跟最上方後臺獲取的一致。
思路:vant的areaList格式必須時以上的。可以把後臺的省放進province_list,市和區也相對應的放進相應的list。
官方提供的json資料很明顯。是根據地區前的數字編碼進行篩選的。編碼為6位,前2位是對應市從11開始。中間2位對應的是市,從01開始。最後的2位編碼是區,也是從01開始。
程式碼如下:
export const mixin1={
methods:{
async getAddress(){//vue mixin
let res=await this.$axios('/other/get-address-all');
let address={};
let province_list={};
let city_list={};
let county_list={};
let n1=110000;
if(res.data.level=='success'){//獲取自主傳入的地址
let arr=[]
res.data.data.forEach((val)=>{
if(val.name!=''){
province_list[n1]=val.name;
if(val.cityList!=''){
// debugger
let n2=110;
let city=val.cityList;
city.forEach(val=>{
city_list[n1+n2]=val.name;
if(val.areaList!=''){
let n3=10;
val.areaList.forEach(val=>{
let obj={};
county_list[n1+n2+n3]=val.name;
obj[val.name]=val.townList
n3+=10
arr.push(obj);
})
n2+=100
// this.$store.dispatch('setTownList',arr)//存入區對應的鎮或街道
}
})
}
n1+=10000;
}
this.$store.dispatch('setTownList',arr)//存入區對應的鎮或街道;
})
}
this.areaList.province_list=province_list;
this.areaList.city_list=city_list;
this.areaList.county_list=county_list;
}
}
}
這裡的邏輯是這樣的,province_list 對應n(n1=110000);areaList.city_list對應n (n2+n1=110+110000);
county_list對應的n是(n3+n2+n1=10+110+110000)
這裡要注意的是,n+=*的放的位置,應該放在當層,並且當層遍歷完才遞增
此外。這2個三級聯動,並不只侷限與地址,也可用於其他的資料(這不是廢話···,自己傳進去的資料)
延申:4級聯動
由於本人的智力有限,在一個元件內實現4級聯動,腦力跟不上。遂用3+1的方法實現···
其實在移動端這樣實現,也有好處,就是看起來3+1比4看起來更好看,不用擠在一起啊
工作地區為3級聯動
街道為沒有聯動
實現思路是這樣。
三級聯動跟上邊提到的一樣。
當選中三級聯動後,獲取到三級聯動的最後一項,如天河區。然後再從town中篩選出來。
town的格式為{‘天河區’:[‘東圃’,‘車陂’],‘番禺’:[‘市橋’,‘沙灣’]…}資料可以跟最上提到的後臺資料一次獲取,也可以另外介面,你喜歡就好。
好了大功告成!!!