Vue+Element UI+Lumen实现通用表格分页功能


Posted in Javascript onFebruary 02, 2019

前言

最近在做一个前后端分离的项目,前端使用 Vue+ Element UI,而后端则使用 Lumen 做接口开发,其中分页是必不可少的一部分,本文就介绍如何基于以上环境做一个简单、可复用的分页功能。

先说后端

后端做的事情不多,只需要接受几个参数,根据参数来获取数据即可。

需要获取的参数如下:

  • pageSize(一页数据的数量)
  • pageIndex(第几页的数据)

然后就可以根据这两个参数计算出偏移量,再从数据库中取出相应的数据。

假如现在给出的参数为:pageSize=10pageIndex = 2,也就是说每一页要10条记录,要第二页。

计算偏移量的公式为: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();
}

后端基本上只需要做这么多,就可以完成一个分页的功能了,但还是有几处地方需要改进一下:

  • 给参数一个默认值
  • 前端还需要知道整个表的数据的总数
  • 把分页做成一个公用的函数

改进后的代码如下:

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来管理状态,然后在请求时带上分页数据:

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>

后记

将一些常用的功能抽象出来,打造一个自己的工具库,从而使开发效率更高。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jQuery 动态酷效果实现总结
Dec 27 Javascript
jquery 选择器引擎sizzle浅析
Feb 06 Javascript
轻量级网页遮罩层jQuery插件用法实例
Jul 31 Javascript
深入理解jQuery之防止冒泡事件
May 24 Javascript
微信小程序组件 contact-button(客服会话按钮)详解及实例代码
Jan 10 Javascript
JavaScript中的call和apply的用途以及区别
Jan 11 Javascript
JavaScript实现反转字符串的方法详解
Apr 27 Javascript
bootstrap的工具提示实例代码
May 17 Javascript
移动端效果之IndexList详解
Oct 20 Javascript
vue项目打包之后背景样式丢失的解决方案
Jan 17 Javascript
15分钟深入了解JS继承分类、原理与用法
Jan 19 Javascript
Vue 通过公共字段,拼接两个对象数组的实例
Nov 07 Javascript
JS基于ES6新特性async await进行异步处理操作示例
Feb 02 #Javascript
JS使用canvas中的measureText方法测量字体宽度示例
Feb 02 #Javascript
JS使用对象的defineProperty进行变量监控操作示例
Feb 02 #Javascript
详解Vue webapp项目通过HBulider打包原生APP(vue+webpack+HBulider)
Feb 02 #Javascript
通过cordova将vue项目打包为webapp的方法
Feb 02 #Javascript
用Cordova打包Vue项目的方法步骤
Feb 02 #Javascript
JS实现数组去重及数组内对象去重功能示例
Feb 02 #Javascript
You might like
杏林同学录(八)
2006/10/09 PHP
PHP 检查扩展库或函数是否可用的代码
2010/04/06 PHP
android上传图片到PHP的过程详解
2015/08/03 PHP
为你总结一些php系统类函数
2015/10/21 PHP
phalcon框架使用指南
2016/02/23 PHP
PHP实现的浏览器检查类
2016/04/11 PHP
yii2带搜索功能的下拉框实例详解
2016/05/12 PHP
PHP获取真实客户端的真实IP
2017/03/07 PHP
ThinkPHP中类的构造函数_construct()与_initialize()的区别详解
2017/03/13 PHP
ThinkPHP 3.2.2实现事务操作的方法
2017/05/05 PHP
jquery实现显示已选用户
2014/07/21 Javascript
Node.js中用D3.js的方法示例
2017/01/16 Javascript
ES6中module模块化开发实例浅析
2017/04/06 Javascript
解决Mac node版本升级失败的问题
2018/05/16 Javascript
微信小程序实现时间进度条功能
2020/11/17 Javascript
用Python创建声明性迷你语言的教程
2015/04/13 Python
python 调用HBase的简单实例
2016/12/18 Python
Python编写登陆接口的方法
2017/07/10 Python
python 常见字符串与函数的用法详解
2018/11/23 Python
Python3.4学习笔记之常用操作符,条件分支和循环用法示例
2019/03/01 Python
Python判断远程服务器上Excel文件是否被人打开的方法
2020/07/13 Python
10款最佳Python开发工具推荐,每一款都是神器
2020/10/15 Python
用ldap作为django后端用户登录验证的实现
2020/12/07 Python
英国高街品牌:Miss Selfridge(塞尔弗里奇小姐)
2016/09/21 全球购物
英国手机零售商:Metrofone
2019/03/18 全球购物
幼儿园实习自我鉴定
2013/12/15 职场文书
《值日生》教学反思
2014/02/17 职场文书
运动会入场词50字
2014/02/20 职场文书
暑假家长评语大全
2014/04/17 职场文书
中专毕业生的自荐书
2014/07/01 职场文书
毕业证委托书范文
2014/09/26 职场文书
单位婚育证明范本
2014/11/21 职场文书
夫妻吵架保证书
2015/05/08 职场文书
消夏晚会主持词
2015/06/30 职场文书
2016年小学教师师德承诺书
2016/03/25 职场文书
JavaScript中的宏任务和微任务详情
2021/11/27 Javascript