springboot+vue实现分页操作

技术栈:

springboot,vue,elementUI

实现效果

springboot+vue实现分页操作_第1张图片

后端

首先我们需要封装一个包装类,来封装我们的分页数据,所以我在这里定义一个RespPageBean

包装类

package com.leo.vhr.model;

import java.util.List;

/**
 * @description:
 * @author: Leo
 * @createDate: 2020/2/1
 * @version: 1.0
 */
public class RespPageBean
{
    private Long total;
    private List<?> data;

    public Long getTotal()
    {
        return total;
    }

    public void setTotal(Long total)
    {
        this.total = total;
    }

    public List<?> getData()
    {
        return data;
    }

    public void setData(List<?> data)
    {
        this.data = data;
    }
}

控制层

package com.leo.vhr.controller.emp;

import com.leo.vhr.model.RespPageBean;
import com.leo.vhr.service.EmployeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @description:
 * @author: Leo
 * @createDate: 2020/2/1
 * @version: 1.0
 */
@RestController
@RequestMapping("/emp/basic")
public class EmpBasicController
{
    @Autowired
    EmployeeService employeeService;
    @GetMapping("/")
    public RespPageBean getEmpByPage(@RequestParam(defaultValue = "1") Integer page,
                                     @RequestParam(defaultValue = "10") Integer size){
        return employeeService.getEmpByPage(page,size);
    }
}

这里写一个方法,将page和size参数传进来并给了默认值

服务层

这里开始实现分页逻辑,分页的基本逻辑是什么呢?

   Select * from product limit 0 ,5
   Select * from product limit 5 ,5
   Select * from product limit 10 ,5
   Select * from product limit 15 ,5

当前页 起始值 每页数据大小
1 0 5
2 5 5
3 10 5
4 15 5
结论
(1)(当前页-1)*(每页数量)=起始值
(2)要想实现分页,向服务端发起请求的时候,必须传递当前页。

返回到实现代码
首先是定义一个方法,定义参数page,size;
获取分页的数据与总页数(这里是根据上面的包装类来写的)
然后将分页获取的数据与总页数set回去

package com.leo.vhr.service;

import com.leo.vhr.mapper.EmployeeMapper;
import com.leo.vhr.model.Employee;
import com.leo.vhr.model.RespPageBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @description:
 * @author: Leo
 * @createDate: 2020/2/1
 * @version: 1.0
 */
@Service
public class EmployeeService
{
    @Autowired
    EmployeeMapper employeeMapper;

    public RespPageBean getEmpByPage(Integer page, Integer size)
    {
        if(page!=null&&size!=null){
            page=(page-1)*size;
        }
        List<Employee> data=employeeMapper.getEmpByPage(page,size);
        Long total=employeeMapper.getTotal();
        RespPageBean bean = new RespPageBean();
        bean.setData(data);
        bean.setTotal(total);
        return bean;
    }
}

Mapper接口

package com.leo.vhr.mapper;

import com.leo.vhr.model.Employee;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface EmployeeMapper {

    List<Employee> getEmpByPage(@Param("page") Integer page,@Param("size") Integer size);

    Long getTotal();
}

xml编写

"1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
"com.leo.vhr.mapper.EmployeeMapper" >
  "BaseResultMap" type="com.leo.vhr.model.Employee" >
    "id" property="id" jdbcType="INTEGER" />
    "name" property="name" jdbcType="VARCHAR" />
    "gender" property="gender" jdbcType="CHAR" />
    "birthday" property="birthday" jdbcType="DATE" />
    "idCard" property="idCard" jdbcType="CHAR" />
    "wedlock" property="wedlock" jdbcType="CHAR" />
    "nationId" property="nationId" jdbcType="INTEGER" />
    "nativePlace" property="nativePlace" jdbcType="VARCHAR" />
    "politicId" property="politicId" jdbcType="INTEGER" />
    "email" property="email" jdbcType="VARCHAR" />
    "phone" property="phone" jdbcType="VARCHAR" />
    "address" property="address" jdbcType="VARCHAR" />
    "departmentId" property="departmentId" jdbcType="INTEGER" />
    "jobLevelId" property="jobLevelId" jdbcType="INTEGER" />
    "posId" property="posId" jdbcType="INTEGER" />
    "engageForm" property="engageForm" jdbcType="VARCHAR" />
    "tiptopDegree" property="tiptopDegree" jdbcType="CHAR" />
    "specialty" property="specialty" jdbcType="VARCHAR" />
    "school" property="school" jdbcType="VARCHAR" />
    "beginDate" property="beginDate" jdbcType="DATE" />
    "workState" property="workState" jdbcType="CHAR" />
    "workID" property="workID" jdbcType="CHAR" />
    "contractTerm" property="contractTerm" jdbcType="DOUBLE" />
    "conversionTime" property="conversionTime" jdbcType="DATE" />
    "notWorkDate" property="notWorkDate" jdbcType="DATE" />
    "beginContract" property="beginContract" jdbcType="DATE" />
    "endContract" property="endContract" jdbcType="DATE" />
    "workAge" property="workAge" jdbcType="INTEGER" />
  </resultMap>

  "AllEmpInfo" type="com.leo.vhr.model.Employee" extends="BaseResultMap">
    "nation" javaType="com.leo.vhr.model.Nation">
      "nid" property="id"></id>
      "nname" property="name"></result>
    </association>
    "politicsstatus" javaType="com.leo.vhr.model.Politicsstatus">
      "pid" property="id"></id>
      "pname" property="name"></result>
    </association>
    "department" javaType="com.leo.vhr.model.Department">
      "did" property="id"></id>
      "dname" property="name"></result>
    </association>
    "jobLevel" javaType="com.leo.vhr.model.JobLevel">
      "jid" property="id"></id>
      "jname" property="name"></result>
    </association>
    "position" javaType="com.leo.vhr.model.Position">
      "posid" property="id"></id>
      "posname" property="name"></result>
    </association>
  </resultMap>
 <select id="getTotal" resultType="java.lang.Long">
    select count(*) from employee
  </select>
  <select id="getEmpByPage" resultMap="AllEmpInfo">
    SELECT e.*,p.id as pid,p.name as pname,n.id nid,n.name nname,d.id did,d.name dname,j.id jid,j.name jname,pos.id posid,pos.name posname
FROM `employee` e,nation n,politicsstatus p,department d,joblevel j,position pos
where e.nationId=n.id and e.politicId=p.id and e.departmentId=d.id and e.jobLevelId=j.id and e.posid=pos.id
limit #{page},#{size}
  </select>
</mapper>

这里只是字段很多,存在一对多关系;看不懂的话,待会对应下面的model来看,理解起来会稍微好点;

Model类

package com.leo.vhr.model;

import com.fasterxml.jackson.annotation.JsonFormat;

import java.util.Date;

public class Employee {
    private Integer id;

    private String name;

    private String gender;

    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "Asia/Shanghai")
    private Date birthday;

    private String idCard;

    private String wedlock;

    private Integer nationId;

    private String nativePlace;

    private Integer politicId;

    private String email;

    private String phone;

    private String address;

    private Integer departmentId;

    private Integer jobLevelId;

    private Integer posId;

    private String engageForm;

    private String tiptopDegree;

    private String specialty;

    private String school;

    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "Asia/Shanghai")
    private Date beginDate;

    private String workState;

    private String workID;

    private Double contractTerm;

    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "Asia/Shanghai")
    private Date conversionTime;

    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "Asia/Shanghai")
    private Date notWorkDate;

    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "Asia/Shanghai")
    private Date beginContract;

    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "Asia/Shanghai")
    private Date endContract;

    private Integer workAge;

    private Nation nation;
    private Politicsstatus politicsstatus;
    private Department department;
    private JobLevel jobLevel;
    private Position position;

   //setter getter
}

前端

先贴完整代码

<template>
  <div>
    <div style="display:flex;justify-content:space-between">
      <div>
        <el-input placeholder="请输入员工名进行搜索..." prefix-icon="el-icon-search"
        style="width:300px;margin-right:10px;"></el-input>
        <el-button icon="el-icon-search" type="primary">搜索</el-button>
        <el-button type="primary"><i class="fa fa-angle-double-down" aria-hidden="true"></i>高级搜索</el-button>
      </div>
      <div>
        <el-button type="success">
          <i class="fa fa-level-up"></i>导入数据</el-button>
        <el-button type="success"><i class="fa fa-level-down"></i>导出数据</el-button>
        <el-button type="success" icon="el-icon-plus">添加用户</el-button>
      </div>
    </div>
    <div style="margin-top:10px">
       <el-table
    :data="emps"
    border
    stripe
    style="width: 100%"
    >
      <el-table-column
      type="selection"
      width="55">
    </el-table-column>
    <el-table-column
      prop="name"
      label="姓名"
      width="90"
      align="left"
      fixed>
    </el-table-column>
    <el-table-column
      prop="workID"
      label="工号"
      width="100"
      align="left">
    </el-table-column>
     <el-table-column
      prop="gender"
      label="性别"
      align="center"
      width="70">
    </el-table-column>
    <el-table-column
      prop="birthday"
      label="出生日期"
      align="left"
      width="100">
    </el-table-column>
        <el-table-column
      prop="idCard"
      label="身份证号"
      align="left"
      width="170">
    </el-table-column>
    <el-table-column
      prop="wedlock"
      label="婚姻状况"
      align="center">
    </el-table-column>
    <el-table-column
      prop="nation.name"
      label="民族"
      width="50">
    </el-table-column>
    <el-table-column
      prop="nativePlace"
      label="籍贯">
    </el-table-column>
    <el-table-column
      prop="politicsstatus.name"
      label="政治面貌">
    </el-table-column>
    <el-table-column
      prop="email"
      label="电子邮件"
      align="left"
      width="180">
    </el-table-column>
    <el-table-column
      prop="phone"
      label="电话号码"
      align="left"
      width="120">
    </el-table-column>
    <el-table-column
      prop="address"
      label="联系地址"
      align="left"
      width="220">
    </el-table-column>
    <el-table-column
      prop="department.name"
      label="所属部门"
      align="left"
      width="100">
    </el-table-column>
    <el-table-column
      prop="position.name"
      label="职位"
      width="100">
    </el-table-column>
    <el-table-column
      prop="jobLevel.name"
      label="职称"
      align="left"
      width="100">
    </el-table-column>
    <el-table-column
      prop="engageForm"
      label="聘用形式"
      align="left"
      width="100">
    </el-table-column>
    <el-table-column
      prop="beginDate"
      label="入职日期"
      align="left"
      width="100">
    </el-table-column>
    <el-table-column
      prop="conversionTime"
      label="转正日期"
      align="left"
      width="100">
    </el-table-column>
    <el-table-column
      prop="beginContract"
      label="合同起始日期"
      align="center" width="120">
    </el-table-column>
    <el-table-column
      prop="endContract"
      label="合同终止日期"
      align="center" width="120">
    </el-table-column>
    <el-table-column
      label="合同期限"
      align="left"
      width="100">
      <template slot-scope="scope">
        <el-tag>{{scope.row.contractTerm}}</el-tag>
      </template>
    </el-table-column>
    <el-table-column
      prop="tiptopDegree"
      label="最高学历"
      align="left"
      width="50">
    </el-table-column>
   <el-table-column
      fixed="right"
      width="200"
      label="操作">
      <template slot-scope="scope">
        <el-button style="padding:3px;"
          size="mini">编辑</el-button>
        <el-button style="padding:3px;"
          size="mini" type="primary">查看高级资料</el-button>
        <el-button style="padding:3px;"
          size="mini"
          type="danger">删除</el-button>
      </template>
    </el-table-column>
  </el-table>
  <div style="display:flex;justify-content:flex-end">
    <el-pagination
  background
  @current-change="currentChange"
  @size-change="sizeChange"
  layout="sizes, prev, pager, next, jumper, ->, total, slot"
  :total="total">
</el-pagination>
  </div>
    </div>
  </div>
</template>

<script>
export default {
  name:"EmpBasic",
  data(){
    return{
      emps:[],
      total:0,
      page:1,
      size:10
    }
  },
  mounted(){
    this.initEmps();
  },
  methods:{
    sizeChange(pageSize){
      //console.log('pageSize:'+pageSize)
      this.size=pageSize;
      this.initEmps();
    },
    currentChange(currentPage){
      //console.log('currentPage:'+currentPage)
      this.page=currentPage;
      this.initEmps();
    },
    initEmps(){
      this.getRequest("/emp/basic/?page="+this.page+"&size="+this.size).then(resp=>{
        if(resp){
          this.emps=resp.data;//这里resp里面返回的数据是个对象,真正的数据在resp的data里;
          this.total=resp.total;
        }
      })
    }
  }
}
</script>

<style>

</style>

结合element官网来说:
https://element.eleme.cn/#/zh-CN/component/pagination

打开官网,选取任意分页组件,将代码复制到前端,当然你要是想要完整的功能,饿了么UI也提供了
springboot+vue实现分页操作_第2张图片

<el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="currentPage4"
      :page-sizes="[100, 200, 300, 400]"
      :page-size="100"
      layout="total, sizes, prev, pager, next, jumper"
      :total="400">
    </el-pagination>

在data里定义一个数组,存放从后端返回的数据
由于分页的方法在后端已经实现,这里我们只需要在前端发送请求,传递参数即可

initEmps(){
      this.getRequest("/emp/basic/?page="+this.page+"&size="+this.size).then(resp=>{
        if(resp){
          this.emps=resp.data;//这里resp里面返回的数据是个对象,真正的数据在resp的data里;
          this.total=resp.total;//后端返回的总数据传给前端
        }
      })
    }

这个getRequest是已经封装好的方法

//为方便统一所有请求,加上前缀,定义一个全局变量;
let base='';
//以get形式传递json
export const getRequest=(url,params)=>{
    return axios({
        method:'get',
        url:`${base}${url}`,
        data:params
    })
}

绑定data

data(){
    return{
      emps:[],
      total:0,
      page:1,
      size:10
    }
  },

点击翻页与设置每页数据量

查看官方文档
springboot+vue实现分页操作_第3张图片

 <el-pagination
  background
  @current-change="currentChange"
  @size-change="sizeChange"
  layout="sizes, prev, pager, next, jumper, ->, total, slot"
  :total="total">
</el-pagination>
sizeChange(pageSize){
      //console.log('pageSize:'+pageSize)
      this.size=pageSize;
      this.initEmps();
    },
currentChange(currentPage){
      //console.log('currentPage:'+currentPage)
      this.page=currentPage;
      this.initEmps();
    },

自己根据松哥的视频做的springboot+vue,留作学习记录。松哥在vhr项目里,前端方面很多地方都进行了封装,有些地方理解起来确实不易。我自己也是一边的跟这视频做,一边的学习新知识,希望可以越来越好吧。

Author By 朝花不迟暮

你可能感兴趣的:(SpringBoot,vue,vue.js,spring,boot)