這幾天做小程序因?yàn)轫?xiàng)目里要做個(gè)行業(yè)分類的二級(jí)聯(lián)動(dòng)灭必,想到了小程序自帶的picker插件告抄,對(duì)照實(shí)例看了一下發(fā)現(xiàn)再姑,小程序picker實(shí)例的數(shù)據(jù)來源格式跟我的項(xiàng)目接口返回的數(shù)據(jù)格式不太一樣丈氓,而且是三級(jí)聯(lián)動(dòng)谬运,所以我準(zhǔn)備把這個(gè)實(shí)例結(jié)構(gòu)改一下扰付,封裝起來,讓大家直接可以拿過來用。
看一下成果展示和我的數(shù)據(jù)格式晚凿,如果數(shù)據(jù)格式和你們正在做的項(xiàng)目一樣,那么就可以直接復(fù)制源代碼使用了塘辅,如果不一樣晃虫,看一下和小程序官方實(shí)例這個(gè)數(shù)據(jù)格式是不是一樣。
我的項(xiàng)目接口返回的數(shù)據(jù)格式是每一項(xiàng)都有一個(gè)子項(xiàng)(childern)字段扣墩;
1.好了哲银,接下來第一步扛吞,我們把小程序picker官方實(shí)例導(dǎo)入進(jìn)來,刪除沒用的單選和時(shí)間地址的picker(wxml和js里無關(guān)代碼都刪除)荆责,留下一個(gè) 多選擇器功能的代碼滥比。
2.修改wxml,因?yàn)槭嵌?jí)聯(lián)動(dòng)做院,所以要把實(shí)例中的第三級(jí){{multiArray[2][multiIndex[2]]}}
給刪除盲泛。
<picker class="pickerSconed" mode="multiSelector"bindchange="bindMultiPickerChange" bindcolumnchange="bindMultiPickerColumnChange" value="{{multiIndex}}" range="{{multiArray}}">
<view class="picker">
{{multiArray[0][multiIndex[0]]}},{{multiArray[1][multiIndex[1]]}}
</view>
</picker>
最后wxml文件中完整的代碼應(yīng)該是這樣键耕。
3.修改js文件寺滚,刪除后的js文件是下面這樣。
Page({
data: {
multiArray: [],
multiIndex: [0, 0],
}
bindMultiPickerChange: function (e) {
},
bindMultiPickerColumnChange: function (e) {
}
})
剩下就是我們隨心所欲的往里面寫自己的內(nèi)容了屈雄,因?yàn)槭且庋b組件使用村视,所以要先使用attached(){}
這個(gè)方法,讓組件調(diào)用時(shí)候就執(zhí)行代碼酒奶。
attached(){
this.getIndustry();
},
/**
* 組件的方法列表
*/
methods: {
// 獲取行業(yè)分類checkCorp.industry
getIndustry() {
let that = this;
httpPost(xxxx接口地址xxxx, {}, res => {
if (res.code == httpCode.success) {
console.log(res.data);
let temporary = { //--------------因?yàn)榻涌跀?shù)據(jù)返回的是從第一項(xiàng)開始的蚁孔,這里加一個(gè)請(qǐng)選擇選項(xiàng)放入數(shù)據(jù)的開頭
label:"請(qǐng)選擇",
value:"0",
children:[{label:'',value:'0'}]
}
let firstList = res.data; //---------------------將一級(jí)分類數(shù)組放入新的變量里便于操作
firstList.unshift(temporary);
console.log(firstList);
let industryName = firstList.map(m => {
return m.label //------------------------獲取一級(jí)下拉列表的名稱
});
that.setData({
multiArray: [industryName, []], //----------- 將一級(jí)列表的名稱存入二維數(shù)組的第一項(xiàng)
firstList, // ------------一級(jí)的完整數(shù)據(jù) 先存著后面有用
industryName //---------------一級(jí)的名稱 先存著后面有用
});
let industryOneId = firstList[0]['value']; // 一級(jí)菜單默認(rèn)的value
if (industryOneId) {
that.searchClassInfo(industryOneId); //如果存在,去掉取相應(yīng)數(shù)組下的list
}
}
})
},
上面是第一部分代碼惋嚎,我盡量都采用這種代碼附注釋的方式逐行講解杠氢。httpPost是我封裝的一個(gè)post請(qǐng)求,最下面會(huì)貼出來另伍。
下面代碼接this.searchClassInfo()這個(gè)方法鼻百,把一級(jí)的value拿到,其實(shí)這個(gè)value就是id质况。searchClassInfo()方法的主要步驟就是:
- 將一級(jí)下拉選中的value取下來
2.根據(jù)存下來的value去firstList里找到相同value的那一項(xiàng)
3.將相同項(xiàng)下的children字段存下來愕宋,并且遍歷出其下的label字段 放入二維數(shù)組的第二位中。
searchClassInfo(value) {
let that = this;
if (value) {
that.setData({
industryOneId: value //這個(gè)是一級(jí)列表中用戶選中的value
});
that.data.firstList.map(m => { //firstList是一級(jí)分類的數(shù)組结榄,上方代碼里有
if (m.value == value) { //通過比對(duì)查出value對(duì)應(yīng)的這一列
that.setData({
secondList: m.children //用戶選中的一級(jí)分類中的children就是第二列的列表
})
}
});
// console.log(that.data.secondList);
let industryTwoName = that.data.secondList.map(m => {
return m.label //再遍歷secondList把所有的label取出來放入industryTwoName 中用于二級(jí)列表的展示
});
// console.log(industryTwoName);
let industryName = that.data.industryName;
that.setData({
multiArray: [industryName, industryTwoName], //這就是一個(gè)完整的二級(jí)聯(lián)動(dòng)展示了
industryTwoName,
})
}
},
然后我們要他的滾動(dòng)狀態(tài)進(jìn)行監(jiān)聽 ,小程序案例中給了這個(gè)方法:bindcolumnchange="bindMultiPickerColumnChange"
中贝,我們直接拿他接著寫
bindMultiPickerColumnChange: function (e) {
let that = this;
console.log('修改的列為', e.detail.column, ',值為', e.detail.value);
var data = {
multiArray: that.data.multiArray,
multiIndex: that.data.multiIndex
};
data.multiIndex[e.detail.column] = e.detail.value; //從這以上的代碼是案例自帶的沒有刪除的臼朗。
/************************************************************/
let industryOneId_session = that.data.industryOneId; // 先將滾動(dòng)前的一級(jí)菜單id存下來邻寿,便于之后做對(duì)比
switch (e.detail.column) {
case 0:
let firstList = that.data.firstList;
var firstId = firstList[e.detail.value]['value'];
if (industryOneId_session != firstId) { //每次滾動(dòng)的時(shí)候都去和上一個(gè)做一次對(duì)比
that.searchClassInfo(firstId); // 只要不一樣,就去執(zhí)行上面searchClassInfo()這個(gè)方法
}
data.multiIndex[1] = 0;
break;
}
}
最后我們需要確定他的改變事件视哑,bindchange="bindMultiPickerChange"
;
bindMultiPickerChange: function (e) {
console.log('picker發(fā)送選擇改變绣否,攜帶值為', e.detail.value);
var secondList = this.data.secondList;
var select_key = e.detail.value[1]; //去二維數(shù)組中第二項(xiàng)的下標(biāo)取出來,也就是二級(jí)下拉菜單的下標(biāo)值
this.setData({
industryTwoId: secondList[select_key]['value'] // 拿到下標(biāo)值對(duì)應(yīng)的value值就是我們要用的id
})
this.setData({
multiIndex: e.detail.value
});
// 通過triggerEvent綁定的myEvent方法挡毅,把一級(jí)下拉的id和二級(jí)下拉的id拿出來
this.triggerEvent('myEvent', { industryOneId: this.data.industryOneId, industryTwoId: this.data.industryTwoId})
},
這樣的話蒜撮,組件就封裝好了,別的頁面調(diào)用的話也很簡單
然后。段磨。
<industry-class class="pickerSconed" bind:myEvent="getData"></industry-class>
bind:myEvent綁定的getData()方法可以取出組件中傳過來的一級(jí)id和二級(jí)id取逾;
getData(e){
let data = e.detail;
this.setData({
industryOneId: data.industryOneId,
industryTwoId: data.industryTwoId
});
console.log(this.data.industryOneId);
console.log(this.data.industryTwoId);
},
最后附上封裝的post方法代碼。
// post請(qǐng)求
function httpPost(url, data, cb) {
wx.request({
url: 'xxx Ip地址 xxx' + url,
data: data,
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded',
},
success: function (res) {
return typeof cb == "function" && cb(res.data)
},
fail: function () {
return typeof cb == "function" && cb(false)
}
})
}