背景介紹:是一個(gè)寄樣登記的表格,初始進(jìn)來(lái)是空的,在右上角有一個(gè)添加寄樣明細(xì)的按鈕,點(diǎn)了添加寄樣明細(xì)之后,會(huì)彈出一個(gè)彈框,有很多很多的產(chǎn)品列表,一頁(yè)有十個(gè)產(chǎn)品,可以通過(guò)選中產(chǎn)品列表,比方說(shuō)當(dāng)前第一頁(yè)選中5條,然后跳轉(zhuǎn)到第二頁(yè),選中6條數(shù)據(jù),再回到第一頁(yè),勾選中的數(shù)據(jù)依然是選中狀態(tài),點(diǎn)擊添加之后,將添加11條數(shù)據(jù)到寄樣登記的表格,從始至終整個(gè)過(guò)程都是在前端完成的,除了打開(kāi)彈窗請(qǐng)求的產(chǎn)品列表需要請(qǐng)求接口。(主要的大致難點(diǎn)在于切換分頁(yè)保存所有選中的數(shù)組,以及要將之前選中的所有數(shù)據(jù)默認(rèn)渲染,以及取消選中的產(chǎn)品也要從所有數(shù)組中刪除。)
大致思路:主要是弄一個(gè)全部選中的數(shù)組tableSelectList,這是一個(gè)二維數(shù)組,根據(jù)當(dāng)前的分頁(yè)頁(yè)碼,來(lái)定位當(dāng)前頁(yè)碼中的選中數(shù)據(jù),即this.tableSelectList[this.queryList.pageNum],每次切換頁(yè)碼的時(shí)候,將需要選中的產(chǎn)品列表的index索引拿到,然后使用插件內(nèi)置的方法this.$refs.multipleTable.toggleRowSelection(this.tableData[row]);,將所有數(shù)據(jù)默認(rèn)選中即可。而且使用二維數(shù)組就可以直接通過(guò)賦值的方式,將取消選中的刪除操作也輕松解決,點(diǎn)擊添加的時(shí)候,使用ES6最新的數(shù)組方法flat(),即可將二維數(shù)組降維成一維數(shù)組。
1.首先,注冊(cè)需要使用的變量
export default{
data(){
return{
tableSelectList:[], //所有選中的數(shù)據(jù),根據(jù)頁(yè)碼的一個(gè)二維數(shù)組
queryList:{ //打開(kāi)彈窗的請(qǐng)求參數(shù)
pageSize:10, //一頁(yè)十條數(shù)據(jù)
pageNum:1,
},
tableData:[] //彈窗中的數(shù)組列表
productList:[] //寄樣登記表格中的數(shù)組
}
}
}
2.在模板的talbe中綁定selection-change的事件,監(jiān)聽(tīng)表格中的選中項(xiàng),最主要是當(dāng)取消選中的時(shí)候,也能觸發(fā)selection-change的事件,彈窗綁定了打開(kāi)的事件監(jiān)聽(tīng)``
<template>
<el-table :data="tableData" @selection-change="getChooseItem" ref="multipleTable">
</el-table>
</template>
3.通過(guò)當(dāng)前分頁(yè)的頁(yè)碼,給當(dāng)前頁(yè)選中的值進(jìn)行賦值
getChooseItem(value){ //表格選中項(xiàng)切換的事件 @selection-change
this.tableSelectList[this.queryList.pageNum]=value;
}
4.寫(xiě)一個(gè)默認(rèn)值渲染的方法,在分頁(yè)切換的時(shí)候調(diào)用這個(gè)方法,這里有一個(gè)坑是不用nextTick()會(huì)無(wú)效,因?yàn)樵O(shè)置選中的時(shí)候,DOM還沒(méi)構(gòu)建好,就會(huì)無(wú)法選中
tableDefaultSelect(){
let rows=[]; //先定義一個(gè)選中行的數(shù)組
if(JSON.stringify(this.tableSelectList)!=='[]'){ //先判定是否有值
let arr=this.tableSelectList[this.queryList.pageNum];
for(let i in arr){
//ES6新出的findIndex,返回符合條件的索引位置,有則返回,無(wú)則返回-1,唯一標(biāo)識(shí)id請(qǐng)根據(jù)實(shí)際修改
if(this.tableData.findIndex(x=>x.id===arr[i].id)>=0){
rows.push(this.tableData.findIndex(x=>x.id===arr[i].id));
}
}
this.$nextTick(()=>{ //等dom更新之后再選中,并且表格一定要設(shè)置ref
if (rows) {
rows.forEach(row => {
this.$refs.multipleTable.toggleRowSelection(this.tableData[row]);
})}
});
}
},
//分頁(yè)切換的時(shí)候請(qǐng)求接口,然后調(diào)用渲染默認(rèn)值的方法
changePage(current){
this.queryList.pageNum=current;
//調(diào)用接口拉取到數(shù)據(jù)之后再調(diào)用渲染默認(rèn)值的方法,調(diào)用接口請(qǐng)自行補(bǔ)充
this.tableDefaultSelect();
},
5.寫(xiě)最后的添加事件,我這里是直接push的,因?yàn)槲以诖蜷_(kāi)彈窗的時(shí)候,會(huì)將寄養(yǎng)登記表格中的已添加數(shù)據(jù)的id發(fā)送給后臺(tái),在獲取列表的時(shí)候,就不會(huì)獲取到已添加的數(shù)據(jù)了。不然的話不光渲染默認(rèn)值不光要比較選中數(shù)據(jù),還要對(duì)寄樣登記表格中的數(shù)據(jù)進(jìn)行默認(rèn)值渲染。
addList(){
if(JSON.stringify(this.tableSelectList)!=='[]'){
let arr=this.tableSelectList.flat();
Array.from(arr,x=>this.queryList.productList.push(x));
}
},
6.如果需要不重復(fù)添加,我也封裝了個(gè)不重復(fù)添加的方法,唯一標(biāo)識(shí)的id請(qǐng)根據(jù)項(xiàng)目實(shí)際進(jìn)行修改
//不重復(fù)添加
noRepeatAddList(value1,value2){
for(let i in value1){
let flag=true;
for(let j in value2){
if(value2[j].id===value1[i].id){
flag=false;
break;
}
}
if(flag){
value2.push(value1[i]);
}
}
},