Vue+Element UI+Lumen實(shí)現(xiàn)通用表格分頁功能
前言
最近在做一個(gè)前后端分離的項(xiàng)目,前端使用 Vue+ Element UI,而后端則使用 Lumen 做接口開發(fā),其中分頁是必不可少的一部分,本文就介紹如何基于以上環(huán)境做一個(gè)簡單、可復(fù)用的分頁功能。
先說后端
后端做的事情不多,只需要接受幾個(gè)參數(shù),根據(jù)參數(shù)來獲取數(shù)據(jù)即可。
需要獲取的參數(shù)如下:
- pageSize(一頁數(shù)據(jù)的數(shù)量)
- pageIndex(第幾頁的數(shù)據(jù))
然后就可以根據(jù)這兩個(gè)參數(shù)計(jì)算出偏移量,再從數(shù)據(jù)庫中取出相應(yīng)的數(shù)據(jù)。
假如現(xiàn)在給出的參數(shù)為:pageSize=10,pageIndex = 2,也就是說每一頁要10條記錄,要第二頁。
計(jì)算偏移量的公式為:pageSize * (pageIndex - 1)。
基本代碼如下:
public function getUser(Request $request){
$pageSize = $request->input('pageSize');
$pageIndex = $request->input('pageIndex');
$offset = $pageSize * ($pageIndex - 1);
return User::offset($offset)
->limit($pageSize)
->get();
}
后端基本上只需要做這么多,就可以完成一個(gè)分頁的功能了,但還是有幾處地方需要改進(jìn)一下:
- 給參數(shù)一個(gè)默認(rèn)值
- 前端還需要知道整個(gè)表的數(shù)據(jù)的總數(shù)
- 把分頁做成一個(gè)公用的函數(shù)
改進(jìn)后的代碼如下:
private $default_page_size = 30;
private $default_page_index = 1;
// 公用分頁
public function pagination($request, $list) {
$pageSize = $request->input('pageSize', $this->default_page_size);
$pageIndex = $request->input('pageIndex', $this->default_page_index);
$offset = $pageSize * ($pageIndex - 1);
$total = $list->count();
$list = $list
->offset($offset)
->limit($pageSize);
return [
'list' => $list->get(),
'total' => $total,
];
}
// 獲取用戶列表
public function getUser(Request $request) {
$list = User::query();
/*
這里可以做一些查詢之類的操作
*/
return $this->pagination($request, $list);
}
再說前端
前端相對(duì)于需要做的事情就比較多了,需要考慮幾點(diǎn):
- 獲取數(shù)據(jù)時(shí)需要帶上分頁的參數(shù)
- 分頁參數(shù)需要進(jìn)行本地持久化,以免刷新頁面回到第一頁(后端設(shè)置的默認(rèn)值)
- 同樣要抽象出一個(gè)通用的分頁組件
獲取數(shù)據(jù)
這里我們用 vuex來管理狀態(tài),然后在請求時(shí)帶上分頁數(shù)據(jù):
store.js:
注意:
- 這里為了方便展示代碼,并沒有使用模塊化,項(xiàng)目中,最好將使用模塊化方便管理。
- 這里默認(rèn)讀者清楚 ES6 的語法
export default new vuex.Store({
state : {
user : {
list: [],
total: 0,
pageIndex: 1,
pageSize: 10,
}
},
mutations: {
updateUser(state, data) {
state.user = {
...state.user,
...data,
}
},
},
actions: {
async getUser({commit,state,getters}) {
// $axios 只是我自己封裝的一個(gè)函數(shù) 這里并不重要
const res = await $axios.get('/user',getters.requestData(state.user))
commit('updateUser',res);
},
},
getters:{
requestData(state) {
return (origin) => {
const {
pageIndex,
pageSize,
} = origin;
const data = {
pageIndex,
pageSize,
};
return data;
}
},
}
})
數(shù)據(jù)持久化
現(xiàn)在如何獲取數(shù)據(jù)已經(jīng)搞定了,數(shù)據(jù)持久化我使用 vuex-localstorage,安裝后,只需要在上面代碼的基礎(chǔ)上添加:
import createPersist from 'vuex-localstorage'
export default new vuex.Store({
// 接著上面的
plugins: [createPersist({
namespace: 'studio-user',
initialState: {},
// ONE_WEEK
expires: 7 * 24 * 60 * 60 * 1e3
})]
})
公用分頁組件
<template>
<el-Pagination
background
layout="total, sizes, prev, pager, next, jumper"
:total="module.total"
:current-page.sync="module.pageIndex"
:page-sizes="module.pageSizes"
:page-size.sync="module.pageSize"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
>
</el-Pagination>
</template>
<script>
export default {
props: {
module: Object
},
methods: {
getData() {
this.$emit("get-data");
},
handleCurrentChange() {
this.getData();
},
handleSizeChange(val) {
this.getData();
}
}
};
</script>
使用分頁組件
<template>
<div class="container">
<el-table
:data="user.list"
style="width: 100%;"
>
<el-table-column
v-for="(item,index) in columns"
:key="index"
:prop="item.prop"
:label="item.label"
align="center"
/>
</el-table>
<pagination
:module="user"
@get-data="getData"
/>
</div>
</template>
<script>
import Pagination from "@/common/components/Pagination";
import { mapActions, mapState } from "vuex";
export default {
components: {
Pagination,
},
data: () => ({
columns: [
{
prop: "name",
label: "姓名"
},
{
prop: "性別",
label: "sex"
},
{
prop: "年齡",
label: "age"
},
]
}),
created() {
this.getData();
},
methods: {
...mapActions({
getData : "getUser",
})
},
computed: {
...mapState(["user"])
}
};
</script>
后記
將一些常用的功能抽象出來,打造一個(gè)自己的工具庫,從而使開發(fā)效率更高。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
在React和Vue中使用Mock.js模擬接口的實(shí)現(xiàn)方法
本文將介紹如何在React和Vue項(xiàng)目中使用Mock.js來模擬接口攔截請求,幫助開發(fā)者在不依賴后端的情況下高效地進(jìn)行前端開發(fā),文中有詳細(xì)的代碼示例供大家參考,需要的朋友可以參考下2024-08-08
關(guān)于vue 結(jié)合原生js 解決echarts resize問題
這篇文章主要介紹了關(guān)于vue 結(jié)合原生js 解決echarts resize問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-07-07
Vue-element-admin?導(dǎo)出json和導(dǎo)入json文件的方法
這篇文章主要介紹了Vue-element-admin導(dǎo)出json和導(dǎo)入json文件,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
使用Vue自定義指令實(shí)現(xiàn)Select組件
這篇文章主要介紹了使用Vue自定義指令實(shí)現(xiàn)Select組件,如果哪位朋友對(duì)vue自定義指令不是多了解的話,此篇文章會(huì)對(duì)你有所幫助的,需要的朋友可以參考下2018-05-05
vue3中使用vuedraggable實(shí)現(xiàn)拖拽el-tree數(shù)據(jù)分組功能
這篇文章主要介紹了vue3中使用vuedraggable實(shí)現(xiàn)拖拽el-tree數(shù)據(jù)分組功能,可以實(shí)現(xiàn)單個(gè)拖拽、雙擊添加、按住ctrl鍵實(shí)現(xiàn)多個(gè)添加,或者按住shift鍵實(shí)現(xiàn)范圍添加,添加到框中的數(shù)據(jù),還能拖拽排序,需要的朋友可以參考下2024-02-02

