一抖僵、el-table多選分頁時边琉,記住其他頁的選中狀態(tài)
實現方法:
核心是el-table-column的reserve-selection屬性
1.通過type="selection"設置復選框列逊躁,重點在于 reserve-selection 屬性斑举,設置為true時筹煮,數據更新之后保留之前選中的數據贮泞。
2.需要表格屬性“row-key”的配合,在使用 reserve-selection 功能的情況下酬土,該屬性是必填的荆忍。將row-key設置為表格中唯一的字段名稱(例如programId)。這樣就實現了后端分頁在翻頁或切換條數時撤缴,記住之前的復選框選項刹枉。
<el-table
:data="tableData"
:row-key="getRowKey"
@selection-change="handleSelectionChange"
>
<el-table-column
type="selection"
width="55"
:reserve-selection="true"
/>
...
</el-table>
getRowKey(row) {
//唯一標識
return row.id
},
handleSelectionChange(selected) {
console.log('選中的數據list---', selected)
},
二、el-table在ajax分頁時支持單頁全選和所有頁全選
界面代碼:
<el-table :data="tableData"
:height="tableHeight"
border
style=" 100%"
ref="table"
@selection-change="handleSelectionChange"
>
<el-table-column prop="id"
fixed
align="center">
<el-table-column type="selection"
width="75">
</el-table-column>
<template slot="header" slot-scope="scope">
<div>
<el-checkbox v-model="checkedAll"
@change="changeCheckAll">所有</el-checkbox>
</div>
</template>
</el-table-column>
......
</el-table>
<pager :pager="pager"
@query="getList"
@setPager="onChangePage"></pager>
table上使用了ref屬性腹泌,因為全選和反選時要用到dom操作方法toggleRowSelection嘶卧,同樣,表格自動鋪滿縱向屏幕時凉袱,也需要進行dom操作芥吟,這并非本節(jié)所講內容,只是簡單提一下专甩,el-table并沒有像layui中的table那樣提供百分比-固定像素的方式響應式制定表格高度钟鸵,我們得手動用js計算瀏覽器屏幕高度。
js部分代碼如下:
import pager from "@/components/table/Pager.vue";
export default {
components: {pager},
data () {
return {
checkedAll: false, //全選所有
}
},
methods: {
// 全選操作
handleSelectionChange (val) {
this.loading = val.length > 0 ? false : true;
this.multipleSelection = val;
},
// 選擇需要的/取消選中
toggleSelection (rows) {
if (rows) {
rows.forEach(row => {
this.$refs.table.toggleRowSelection(row);
});
} else {
this.$refs.table.clearSelection();
}
},
//改變全選所有復選框
changeCheckAll (val) {
if (val) {
// 全選選中時當前頁所有數據選中
this.tableData.forEach(row => {
if (row) {
this.$refs.table.toggleRowSelection(row, true);
}
});
} else {
this.$refs.table.clearSelection();
}
},
}
}
在每次點擊“頁碼“之后涤躲,會自動執(zhí)行查詢方法棺耍,此時,如果點擊了全選所有按鈕种樱,要在數據執(zhí)行查詢之后蒙袍,再選中當前頁面所有項,代碼如下所示:
由于所有的dom操作要在dom渲染之后執(zhí)行嫩挤,所以使用了this.$nextTick()方法害幅。
//執(zhí)行查詢方法getList后回調函數當中編寫如下代碼:
if(this.checkedAll){
this.$nextTick(()=>{
this.changeCheckAll(this.checkedAll);
})
}
在element-ui的Table組件當中,并沒有提供給表頭當中的復選框設置文本的屬性和方法岂昭,我們可以通過使用css偽類來創(chuàng)建文本以现。
/deep/用于在css作用域當中進行樣式透傳,覆蓋子組件的樣式约啊。
/deep/ .el-table__header .el-table-column--selection .cell .el-checkbox:after {
content: "當頁";
color: #606266;
font-weight: 500;
margin-left: 10px;
font-size: 14px;
}
分頁組件Pager.vue是對el-pagination組件的二次封裝邑遏,其代碼如下:
最重要的一點,就是所有頁全選時的id集合恰矩,是每次查詢時傳遞過來的记盒,將其臨時存儲在data中,這樣的話需要進行批量操作時外傅,可以直接將這些id集合傳遞過去孽鸡。當然蹂午,如果查詢接口不把這些id集合帶過來,我們也可以傳一個所有頁全選的標識給到后端彬碱,后端根據這個標識,重新去查詢數據奥洼。
<!-- 分頁查詢
<pager :pager=[分頁對象] @query=[列表查詢方法] />
-->
<template>
<div class="pagination-box clear">
<span class="page-total fl">
共有記錄:
<span>{{ pager.total }}</span>條
</span>
<el-pagination
:small="small"
:layout="layout"
background
:pager-count="7"
:total="pager.total"
:current-page.sync="pager.pageNum"
:page-size="pager.pageSize"
:page-sizes="pageSize"
@size-change="onChangeSize"
@current-change="onChangePage"
></el-pagination>
<span v-if="refresh" class="btn-refresh fn-right" title="刷新" @click="$emit('query')">
<i class="fas fa-redo"></i>
</span>
</div>
</template>
<script>
export default {
name: "Pager",
props: {
small: {
type: Boolean,
default: false
},
layout: {
type: String,
default: "sizes,jumper, prev, pager, next"
},
pager: {
type: Object,
required: true
},
refresh: {
type: Boolean
},
pageSize: {
type: Array,
default: () => {
return [10, 15, 20, 50, 100, 200];
}
},
props: {
type: Object,
required: false,
default: () => ({
pageNum: "pageNum", // 第幾頁
pageSize: "pageSize", // 顯示條數
total: "total" // 總記錄條數
})
}
},
// 設置綁定參數
model: {
prop: "pager",
event: "setPager"
},
computed: {
total() {
return this.pager[this.props.total] || 0;
},
// 檢測獲取到的數據是否為空
isEmptyList() {
return (
Math.ceil(
this.pager[this.props.total] / this.pager[this.props.pageSize]
) < this.pager[this.props.pageNum]
);
}
},
watch: {
total() {
// 存在記錄但未獲取到數據時, 重新請求
if (this.pager[this.props.pageNum] > 1 && this.isEmptyList) {
this.$emit(
"setPager",
Object.assign(this.pager, {
[this.props.pageNum]: this.pager[this.props.pageNum] - 1
})
);
this.$emit("query");
}
}
},
methods: {
// 每頁條數
onChangeSize(pageSize) {
const temp = {
[this.props.pageSize]: pageSize,
// 當顯示條數小于或等于總條數時巷疼,重置頁數
[this.props.pageNum]:
pageSize <= this.total ? 1 : this.pager[this.props.pageNum]
};
this.$emit("setPager", Object.assign(this.pager, temp));
// 觸發(fā)父組件查詢請求
this.$emit("query");
},
// 翻頁
onChangePage(pageNum) {
this.$emit(
"setPager",
Object.assign(this.pager, { [this.props.pageNum]: pageNum })
);
this.$emit("query");
}
}
};
</script>
<style lang="scss" scoped>
.pagination-box {
100%;
padding-top: 14px;
position: relative;
.el-pagination {
float: right;
}
/deep/ .el-pagination__sizes {
position: absolute;
top: 14px;
left: 150px !important;
}
}
.page-total {
padding-left: 20px;
height: 31px;
line-height: 31px;
font-size: 14px;
color: #838383;
}
.page-total span {
color: #3a3a3a;
}
.closeBtn {
text-align: center;
margin-top: 10px;
}
.el-input--small .el-input__inner {
height: 25px;
line-height: 25px;
}
.el-input__inner {
border-color: #838383;
}
.el-pagination .btn-next .el-icon,
.el-pagination .btn-prev .el-icon {
font-size: 19px;
position: relative;
top: -3px;
}
.el-pager li {
margin: 0 8px;
border-radius: 3px;
height: 24px;
line-height: 24px;
min- 20px;
}
.el-pager li.active {
background: #1881bf !important;
}
.el-pagination__jump {
margin-right: 20px;
font-size: 14px;
color: #838383;
}
.el-pagination__jump .pagination__editor {
margin-right: 20px;
}
.el-pagination__jump .el-pagination__editor.el-input {
28px;
}
.el-pagination__jump .el-input__inner {
box-sizing: border-box;
100%;
color: #3a3a3a;
font-size: 14px;
border-color: #838383 !important;
height: 24px;
line-height: 24px;
border-radius: 3px;
background: #fff !important;
}
.el-pagination .el-select .el-input .el-input__inner {
border-radius: 15px !important;
font-size: 14px;
border-color: #838383 !important;
background: #fff !important;
}
.el-button--text > span > span {
color: #1881bf;
font-size: 12px;
text-decoration: underline;
}
</style>