要開發一個這樣的多級多選菜單組件,功能是:
- 點擊父標題欄可以打開與摺疊子列表
- 點擊父標題欄的勾選圖標可以全選或取消子列表
- 點擊子列表的勾選圖標達到全選時,父標題欄的勾選圖標自動勾選;反之,沒達到全選時,父標題欄的勾選圖標自動取消勾選
- 當所有父標題欄的勾選圖標達到全選時,最底下那個全選框自動勾選;反之,沒達到全選時,最底下那個全選框自動取消勾選
點擊最底下那個全選框可以全選或取消全部的勾選圖標
所以總結起來我們重點要利用子列表勾選了哪些項來計算出父標題與底下的全選框是自動勾選還是自動取消,並且父標題與底下的全選框在選擇變化時子列表應有什麼變化。要做到以上,實現過程是:
構建我們model層數據
datas : [
{
//用於判斷是否展示子列表
isShowListItem : false,
//用於記錄選中了哪些子項
selected : [],
//父標題
listTitle : "保利南悅灣",
//子列表
listItem : [
{
id : 1,
name : "李小龍"
},
{
id : 2,
name : "周星馳"
},
{
id : 3,
name : "周杰倫"
}
]
},
{
isShowListItem : false,
selected : [],
listTitle : "南莊萬科城",
listItem : [
{
id : 4,
name : "大魔王"
},
{
id : 5,
name : "老妖怪"
}
]
}
]
記錄子列表勾選了哪些項
子列表通過v-model=”data.selected”去雙向綁定到selected數組中,當子列表項的checked發生變化時,就會把當前項的id記錄到selected數組裏去
<input
type="checkbox"
:value="item.id"
v-model="data.selected"
>
當父標題勾選變化時的處理方法
自動處理父標題勾選圖標的變化
在HTML裏,通過綁定:checked=”isTitleChecked(data)”,這時,每當其他項變化時,父標題都會調用一下isTitleChecked這個方法去判斷一下這時自己的checked狀態是true還是false,從而達到根據子項選中數目不同,父標題自動變化的目的。
通過@change=”changeTitleChecked(data,$event)”,每當父標題主動勾選或取消時觸發
父標題HTML
<input :id="data.listTitle"
class="list-input"
type="checkbox"
:checked="isTitleChecked(data)"
@change="changeTitleChecked(data,$event)"
>
父標題JS
- changeTitleChecked方法:當主動觸發父標題的勾選圖標時,如果這次觸發chaeked的狀態是true,則要把子列表項中沒選中的全部選中,即將它們全部加進selected數組中;如果是false,則要把子列表項全部取消選中,即清空selected數組。
- isTitleChecked方法:當子列表項全部選中時自動勾選父標題。
/**
* 當父標題狀態變化時的處理方法
* @param data [當前項的data]
* @param event [當前項的event]
*/
changeTitleChecked : function (data,event) {
if (event.target.checked === true) {
data.listItem.forEach(function (item) {
data.selected.indexOf(item.id) === -1 && data.selected.push(item.id);
})
}else {
data.selected = [];
}
}
/**
* 判斷父標題選擇狀態
* @param data [當前項的data]
* @returns {boolean}
*/
isTitleChecked : function (data) {
var _selected = data.selected;
var _listItem = data.listItem;
// 驗證selected中是否含有全部的item的id 如果是 證明title要選中
return _listItem.every(function (item) {
return _selected.indexOf(item.id) != -1;
});
}
當底下的全選框變化時的處理方法
自動處理底下的全選框的變化
全選框HTML:
<input id="all-checked"
type="checkbox"
:checked="isAllChecked()"
@change="changeAllChecked($event)"
>
全選框JS:
- changeAllChecked方法:當主動觸發全選框時,如果checked爲true,則將全部的子項都放進selected數組裏;反之則清空全部selected數組。
- isAllChecked 方法:判斷selected數組的長度是否等於全部子項數,如果相等,則全選框checked狀態設爲true。
/**
* 全選框change事件的回調處理方法
* @param event
*/
changeAllChecked : function (event) {
if (event.target.checked === true) {
this.datas.forEach(function (data) {
data.listItem.forEach(function (item) {
data.selected.indexOf(item.id) === -1 && data.selected.push(item.id);
})
})
}else {
this.datas.forEach(function (data) {
data.selected = [];
})
}
}
/**
* 判斷全選框選擇狀態
* @returns {boolean}
*/
isAllChecked : function () {
return this.datas.every(function (data) {
return data.selected.length === data.listItem.length;
});
}