此案例基於 基於element-ui的 動態列分頁表格組件(動態控制表格列的顯隱),增加了後端分頁的功能。
實現思路
後端分頁就是前端傳遞頁碼和每頁條數兩個參數到後臺進行查詢,返回的數據僅僅包含當前頁的數據。(不同於前端分頁,一次性查詢所有數據)所以,當頁碼和每頁條數變化時,都需要觸發後端分頁查詢的方法,然後再處理分頁數據。
後端分頁查詢方法是在父組件(組件使用者)定義,所以組件需要通過 $emit 來觸發該方法。
當前頁碼、每頁條數的信息是封裝在組件中的,可以通過 $emit 傳遞給父組件,所以,父組件的後端分頁查詢方法需要有兩個參數接收。
整體流程:
組件 -> $emit -> 父組件分頁查詢方法 -> 發送異步請求到後臺 -> 分頁數據 -> 組件(處理數據,渲染表格)
後端分頁查詢方法一般爲異步請求,$emit 只是觸發該請求,可能分頁數據還沒返回 $emit 就已經執行結束了,那分頁數據怎麼送到組件處理呢?
兩種方式:
- 將分頁數據的處理邏輯以方法參數的形式通過 $emit 傳遞給父組件,由父組件觸發。(此形式)
- 將分頁數據的處理邏輯封裝成一個方法,父組件通過 $refs 調用組件該方法。(本案例使用此方式)
組件功能:
- 繼承 動態列分頁表格組件 的所有功能
- 後端分頁功能開關
- 支持後端分頁
效果圖
和前端分頁效果圖一致,不貼了,直接到在線演示地址看效果吧。
在線演示地址
https://7wuy1.csb.app/#/backendPaging
組件代碼
代碼稍長,必要的註釋都註明在代碼中,文末附使用案例。建議先跑起來使用案例看效果,再深入代碼。
代碼上傳在 前端代碼在線編輯器codesandbox 中,可直接查看編輯:此鏈接
代碼就不直接貼了,直接在 codesandbox上看吧。
使用案例
<template>
<div>
<pre>
後端分頁案例:
1、開啓後端分頁功能:設置backendPaging爲true
2、設置後端分頁查詢方法:設置backendPagingFunc事件。(組件會通過 $emit來觸發該事件,傳遞兩個參數:當前頁碼、每頁條數)
3、通過 $refs 調用組件的 callback方法,傳遞分頁信息給組件。(用於組件渲染表格)
</pre>
<PageTable
:backendPaging="true"
@backendPagingFunc="backendPagingFunc"
:currentPage="2"
:pageSizes="[20,5,10]"
:pageSize="5"
:paging="true"
ref="dataTable"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="賬號" prop="name"></el-table-column>
<el-table-column label="名稱" prop="nickname"></el-table-column>
<el-table-column label="郵箱" prop="email"></el-table-column>
<el-table-column label="狀態">
<template slot-scope="scope">{{ scope.row.state%2===0?'正常':'鎖定' }}</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template slot-scope="scope">
<el-button size="small" type="text" @click.stop="clickFunc(scope.row)">操作按鈕</el-button>
</template>
</el-table-column>
</PageTable>
</div>
</template>
<script>
import PageTable from "./PageTable.vue";
export default {
components: {
PageTable
},
data() {
return {
tableData: []
};
},
methods: {
// 後臺分頁查詢方法,由組件通過 $emit觸發。參數爲當前頁碼、每頁條數、分頁數據回調方法
backendPagingFunc(page, size, callback) {
var params = {};
params.size = size;
params.page = page;
//模擬發送後臺異步請求,延遲3s
console.log("發送後臺請求...", params);
setTimeout(() => {
// 模擬後臺分頁查詢數據
let total = 37, //總條數
arr = new Array(total).fill("").map((_, i) => {
i = i + 1;
return { name: i, nickname: i, email: i, state: i };
}),
pageData = arr.slice(
(params.page - 1) * params.size,
params.page * params.size
);
let result = {
data: pageData,
total: total
};
console.log("後臺請求返回,執行回調", result);
// 由於是後臺分頁,所以需要返回當前頁數據和總條數信息。約定格式爲:{data:[], total:10}
// callback(result);
this.$refs.dataTable.callback(result);
}, 3000);
},
clickFunc(row) {
// console.log(row);
alert(JSON.stringify(row));
}
},
mounted() {}
};
</script>
<style lang="scss" scoped>
</style>
系列文章
end