Vue + Element UI + Lumen 實現通用表格功能 - 分頁

前言

最近在作一個先後端分離的項目,前端使用 Vue+ Element UI,然後端則使用 Lumen 作接口開發,其中分頁是必不可少的一部分,本文就介紹如何基於以上環境作一個簡單、可複用的分頁功能。javascript

先說後端

後端作的事情很少,只須要接受幾個參數,根據參數來獲取數據便可。php

須要獲取的參數以下:html

  • pageSize(一頁數據的數量)
  • pageIndex(第幾頁的數據)

而後就能夠根據這兩個參數計算出偏移量,再從數據庫中取出相應的數據。前端

假如如今給出的參數爲:pageSize=10pageIndex = 2,也就是說每一頁要10條記錄,要第二頁。vue

計算偏移量的公式爲:pageSize * (pageIndex - 1)java

基本代碼以下:ios

public function getUser(Request $request){
    $pageSize = $request->input('pageSize');
    $pageIndex = $request->input('pageIndex');
    $offset = $pageSize * ($pageIndex - 1);
    return User::offset($offset)
                ->limit($pageSize)
                ->get();
}
複製代碼

後端基本上只須要作這麼多,就能夠完成一個分頁的功能了,但仍是有幾處地方須要改進一下:git

  • 給參數一個默認值
  • 前端還須要知道整個表的數據的總數
  • 把分頁作成一個公用的函數

改進後的代碼以下:github

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);
}
複製代碼

再說前端

前端相對於須要作的事情就比較多了,須要考慮幾點:vuex

  • 獲取數據時須要帶上分頁的參數
  • 分頁參數須要進行本地持久化,以避免刷新頁面回到第一頁(後端設置的默認值)
  • 一樣要抽象出一個通用的分頁組件

獲取數據

這裏咱們用 vuex來管理狀態,而後在請求時帶上分頁數據:

store.js:

注意

  • 這裏爲了方便展現代碼,並無使用模塊化,項目中,最好將使用模塊化方便管理。
  • 這裏默認讀者清楚 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 只是我本身封裝的一個函數 這裏並不重要
            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;
            }
        },
    }
})
複製代碼

數據持久化

如今如何獲取數據已經搞定了,數據持久化我使用 vuex-localstorage,安裝後,只須要在上面代碼的基礎上添加:

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>
複製代碼

後記

將一些經常使用的功能抽象出來,打造一個本身的工具庫,從而使開發效率更高。

最後,貼上剛放假時立的 Flag:寒假待寫文章

最後的最後,安利一下文章開頭說的項目:清技背單詞,上面的代碼就是從這個項目中copy出來後略做修改的。

感謝觀看,但願個人文章能對您有一些幫助!

相關文章
相關標籤/搜索