Vue2.0+ElementUI+PageHelper实现的表格分页功能

前言

最近做了一些前端的项目,要对表格进行一些分页显示。表格分页的方法有很多,从宏观上来说分为物理分页和逻辑分页,由于逻辑分页(即前端分页)的做法是将数据全部缓存,然后分页显示,这样在数据量较大的时候会对浏览器的速度产生影响,所以考虑之后我使用了后端分页,后端分页的特点是对当前页的数据进行请求,每次当页码变化或者每页数据量变化的时候,就重新发一次请求。这里所用到的技术主要有以下几种:

  • Spring
  • SpringMVC
  • Mybatis
  • VueJS 2.0
  • ElementUI

后端数据库用的是Mysql,其实使用其他的数据库也可以,因为PageHelper插件里有对于各个数据库的兼容。PageHelper的本质是插入一个Interceptor,在mybatis的sql语句执行之前进行分页处理,本质上是加了两个limit的参数。对于PageHelper的配置和用法,请参考Spring + Mybatis 使用 PageHelper 插件分页这篇文章,这里不再赘述。

前端所使用的是最近很火的vuejs框架2.0,这是一个mvvm架构的框架,类似于AngularJS,但是更加轻量。UI框架使用的是由饿了么团队推出的elementUI框架,这是一款基于vuejs的框架,正好和我们的前端框架完美结合,并且封装了很多组件,开发起来很方便。
下面就是这个Demo的截图,实现了基本的增删改查功能,表格排序是elementUI的表格控件里自带的一个属性,可以很方便的设置。

正文

下面是程序的截图,右键在新标签页中打开图片可以看得清楚些。

下面来看一下前端的代码,首先是引入的文件:

    <link rel="stylesheet" href="/core/element-ui/lib/theme-default/index.css" rel="external nofollow" >
    <script src="./js/jquery-3.1.1.min.js"></script>
    <script src="./js/json2.js"></script>
    <script src="./js/vue.min.js"></script>
    <script src="./js/vue-resource.js"></script>
    <script src="./element-ui/lib/index.js"></script>

其中第一行和最后一行是ElementUI的导入包,可以从ElementUI官网下载到源文件引入,也可以直接使用CDN的方式来引入:

<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-default/index.css" rel="external nofollow" >
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>

倒数第二行vue-resource是vuejs的一个ajax插件,可以通过XMLHttpRequest或JSONP发起请求并处理响应。简单的说,就是可以用来发送ajax请求。

接下来是style样式

    <style>
      .el-select .el-input {
        width: 110px;
      }

      .el-table .info-row {
            background: #c9e5f5;
      }   

      #top {
          background:#20A0FF;
          padding:5px;
          overflow:hidden
      }
    </style>

HTML body

    <div id="test">             

        <div id="top">
            <span style="float:right;">
                <el-button type="text" @click="add" style="color:white">添加</el-button>
                <el-button type="text" @click="deletenames" style="color:white">批量删除</el-button>
            </span>
        </div>  

        <br/>

        <div style="margin-top:15px">
           <el-input placeholder="请输入内容" v-model="criteria" style="padding-bottom:10px;">
              <el-select v-model="select" slot="prepend" placeholder="请选择">
                 <el-option label="id" value="1"></el-option>
                 <el-option label="name" value="2"></el-option>
              </el-select>
              <el-button slot="append" icon="search" v-on:click="search"></el-button>
          </el-input>       

          <el-table
            ref="testTable"
            :data="tableData"
            style="width:100%"
            border
            :default-sort = "{prop: 'id', order: 'ascending'}"
            @selection-change="handleSelectionChange"
            @row-click="handleclick"
            :row-class-name = "tableRowClassName"
            >
            <el-table-column
              type="selection"
              >
            </el-table-column>
            <el-table-column
              prop="id"
              label="Id"
              sortable
              show-overflow-tooltip>
            </el-table-column>
            <el-table-column
              prop="name"
              label="姓名"
              sortable>
            </el-table-column>
            <el-table-column label="操作">
              <template scope="scope">
                <el-button
                  size="small"
                  type="primary"
                  @click="handleEdit(scope.$index, scope.row)">编辑</el-button>
                <el-button
                  size="small"
                  type="danger"
                  @click="handleDelete(scope.$index, scope.row)">删除</el-button>
              </template>
            </el-table-column>
          </el-table>

          <div align="center">
              <el-pagination
                  @size-change="handleSizeChange"
                  @current-change="handleCurrentChange"
                  :current-page="currentPage"
                  :page-sizes="[10, 20, 30, 40]"
                  :page-size="pagesize"
                  layout="total, sizes, prev, pager, next, jumper"
                  :total="totalCount">
              </el-pagination>
          </div>
        </div>
    </div>

    <footer align="center">
        <p>&copy; Vue.js 2.0 + ElementUI分页Demo</p>
    </footer>

接下来是比较重要的创建vue实例。这里使用ES5的写法。

    <script>
    var vue = new Vue({
            el:"#test",
            data: {
                //表格当前页数据
                tableData: [],

                //多选数组
                multipleSelection: [],

                //请求的URL
                url:'newstu/querystudentbypage',

                //搜索条件
                criteria: '',

                //下拉菜单选项
                select: '',

                //默认每页数据量
                pagesize: 10,

                //默认高亮行数据id
                highlightId: -1,

                //当前页码
                currentPage: 1,

                //查询的页码
                start: 1,

                //默认数据总数
                totalCount: 1000,
            },

            methods: {

                //从服务器读取数据
                loadData: function(criteria, pageNum, pageSize){
                    this.$http.get(this.url,{parameter:criteria, pageNum:pageNum, pageSize:pageSize}).then(function(res){
                        this.tableData = res.data.pagestudentdata;
                        this.totalCount = res.data.number;
                    },function(){
                        console.log('failed');
                    });
                },

                //多选响应
                handleSelectionChange: function(val) {
                    this.multipleSelection = val;
                },

                //点击行响应
                handleclick: function(row, event, column){
                    this.highlightId = row.id;
                },

                //编辑
                handleEdit: function(index, row) {
                    this.$prompt('请输入新名称', '提示', {
                          confirmButtonText: '确定',
                          cancelButtonText: '取消',
                        }).then(({ value }) => {
                            if(value==''||value==null)
                                return;
                            this.$http.post('newstu/update',{"id":row.id,"name":value},{emulateJSON: true}).then(function(res){
                                this.loadData(this.criteria, this.currentPage, this.pagesize);
                            },function(){
                                console.log('failed');
                            });
                        }).catch(() => {

                    });
                },

                //单行删除
                handleDelete: function(index, row) {
                    var array = [];
                    array.push(row.id);
                    this.$http.post('newstu/delete',{"array":array},{emulateJSON: true}).then(function(res){
                        this.loadData(this.criteria, this.currentPage, this.pagesize);
                    },function(){
                        console.log('failed');
                    });
                },

                //搜索
                search: function(){
                    this.loadData(this.criteria, this.currentPage, this.pagesize);
                },

                //添加
                add: function(){
                        this.$prompt('请输入名称', '提示', {
                          confirmButtonText: '确定',
                          cancelButtonText: '取消',
                        }).then(({ value }) => {
                            if(value==''||value==null)
                                return;
                            this.$http.post('newstu/add',{"name":value},{emulateJSON: true}).then(function(res){
                                this.loadData(this.criteria, this.currentPage, this.pagesize);
                            },function(){
                                console.log('failed');
                            });
                        }).catch(() => {

                    });

                },

                //多项删除
                deletenames: function(){
                    if(this.multipleSelection.length==0)
                        return;
                    var array = [];
                    this.multipleSelection.forEach((item) => {
                        array.push(item.id);
                    })
                    this.$http.post('newstu/delete',{"array":array},{emulateJSON: true}).then(function(res){
                        this.loadData(this.criteria, this.currentPage, this.pagesize);
                    },function(){
                        console.log('failed');
                    });
                },

                //改变当前点击的行的class,高亮当前行
                tableRowClassName: function(row, index){
                   if(row.id == this.highlightId)
                   {
                      return 'info-row';
                   }
                },

                //每页显示数据量变更
                handleSizeChange: function(val) {
                    this.pagesize = val;
                    this.loadData(this.criteria, this.currentPage, this.pagesize);
                },

                //页码变更
                handleCurrentChange: function(val) {
                    this.currentPage = val;
                    this.loadData(this.criteria, this.currentPage, this.pagesize);
                },        

            },      

          });

          //载入数据
          vue.loadData(vue.criteria, vue.currentPage, vue.pagesize);
    </script>  

现在对上述代码进行一个简单的解释,tableData是表格当前页所显示的数据的数组,当网页加载出来后,首先执行loadData方法,criteria是当前的搜索条件,默认为空,第二个参数是当前页码,默认为第一页,第三个参数为偏移量,即想查询的数量,也就是当前每页所含有的数据量。当页码或每页数据量改变时都会以这些参数的新值作为参数重新调用这个方法。我们可以看一下Controller的代码:

    @ResponseBody
    @RequestMapping(value = "/querystudentbypage", method = RequestMethod.GET)
    public Map<String, Object> querystudentbypage(@RequestParam(value="parameter")String parameter,
            @RequestParam(value="pageNum")int pageNum, @RequestParam(value="pageSize")int pageSize)
    {
        Page<Student> page = iNewStudentService.selectStudents(parameter, pageNum, pageSize);
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("pagestudentdata", page);
        map.put("number", page.getTotal());
        return map;
    } 

ce的实现代码:

    public Page<Student> selectStudents(String parameter, int pageNum, int pageSize)
    {
        Page<Student> page = PageHelper.startPage(pageNum, pageSize);
        newstudentMapper.selectStudents(parameter);
        return page;
    }

mybatis的代码

    <select id="selectStudents" resultMap="NewStudentResultMap">
        select id,name from student where id=#{parameter} or name like CONCAT('%',#{parameter},'%')
    </select>

注:为了代码的简便,这里对用户的输入进行了模糊处理,数据表中的id字段等于用户的输入或name字段包含了用户的输入都可以被查询出来。

从上面的service实现类和mabatis的代码中可以看出,我们并没有手动去给sql语句加limit,而是在newstudentMapper.selectStudents(parameter);这句代码之前加入了Page page = PageHelper.startPage(pageNum, pageSize);这句代码就是对PageHelper的调用,不需要去管PageHelper如何去实现(实际是通过Interceptor),只需要这一句代码就可以做出物理分页。它会对紧跟在它后面的一个sql查询起作用,并且返回分页后的当页代码。
Controller中的map我们可以看到put了两个值,一个是返回的List,另一个是数据总量。前端的表格控件会用到这个LIst,而分页控件会用到这个数据总量。注意startPage的参数,第一个是想要请求的页码,第二个是请求页的数据量。这两个要与前端请求时发送的参数相对应。

程序的其他基本功能包括添加、修改、删除、批量删除等,前端的代码都做了解释,后端也只是单纯的调数据库而已,这里就不再贴上后端的代码。

注:
表格行点击高亮功能在ElementUI的表格控件中通过添加highlight-current-row属性可以设置,不过高亮的颜色被封装到了css文件里。我这里没有用到这个属性,而是自定义了一个class的style,当点击某行时把自定义的style赋给当前行。如果对ElementUI本身的高亮颜色不满意又不想去改css文件的话,可以像文中这种方式自定义一个行点击响应。

写在最后的话

vuejs作为一个前端控件,在最近几年越来越受欢迎,它的社区很活跃,同时又有大量的开源项目库与之配套,详细列表请参考Vue 开源项目库汇总。如果将vuejs与开源库整合使用,将大大提升前端开发效率,尤其是对于像我这样对前端并不是很熟悉的后端工程师,也是可以对照着官网上面的教程和例子进行前端开发。如果使用ES6的写法,那么模块化会更加轻松。

ElementUI也是一套很不错的组件库,对于我们经常用到的表格、表单、时间日期选择器等常用组件都有着很好的封装和接口。

PageHelper作为一个国人写的mybatis分页插件,有着相当不错的表现,并且支持当前所有的主流数据库,使用起来也很方便。

前端开发所需要学习的东西并不比后端开发少多少,而且更需要一个经验的积累,在此记录一下学习前端开发的历程。

到此这篇关于Vue2.0+ElementUI+PageHelper实现的表格分页功能的文章就介绍到这了,更多相关Vue2.0 ElementUI PageHelper表格分页内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue实现表格分页功能

    本文实例为大家分享了vue实现表格分页功能的具体代码,供大家参考,具体内容如下 直接上代码: 这里是这里是template部分,主要由一个需要分页的表格和一个分页器组成.重点在于表格的data属性用到了一个slice截取方法. <el-table v-loading="listLoading" :data=" list.slice((currentPage - 1) * pageSize, currentPage * pageSize) " element-l

  • Javascript vue.js表格分页,ajax异步加载数据

    分页一般和表格一起用,分页链接作为表格的一部分,将分页链接封装成一个独立的组件,然后作为子组件嵌入到表格组件中,这样比较合理. 效果: 代码: 1.注册一个组件 js Vue.component('pagination',{ template:'#paginationTpl', replace:true, props:['cur','all','pageNum'], methods:{ //页码点击事件 btnClick: function(index){ if(index != this.cu

  • vue.js表格分页示例

    分页一般和表格一起用,分页链接作为表格的一部分,将分页链接封装成一个独立的组件,然后作为子组件嵌入到表格组件中,这样比较合理. 效果: 代码: 1.注册一个组件 js Vue.component('pagination',{ template:'#paginationTpl', replace:true, props:['cur','all','pageNum'], methods:{ //页码点击事件 btnClick: function(index){ if(index != this.cu

  • Vue+ElementUI table实现表格分页

    Vue+ElementUI table表格分页,供大家参考,具体内容如下 分页的两种方式.前端分页,后端分页.两种方式各有个的优缺点吧. 前端分页:后台只需将数据返回,不需要做过多处理,前端一次请求拿到所有数据后做分页处理.但数据量不能太大,因为前端是先一次性加载所有数据,然后在做分页处理.在数据量多的情况下,加载相对应的会变慢.所有在前端做分页时要先考虑一下后期的数据量. 后端分页:因为是后端分页,前端在每点击一次分页时,便向后台请求一次数据.其实就是避免前端一次性从数据库获取大量数据 一.在

  • vue.js 表格分页ajax 异步加载数据

    Vue.js是一个轻巧.高性能.可组件化的MVVM库,同时拥有非常容易上手的API. 分页一般和表格一起用,分页链接作为表格的一部分,将分页链接封装成一个独立的组件,然后作为子组件嵌入到表格组件中,这样比较合理. 1.注册一个组件 js Vue.component('pagination',{ template:'#paginationTpl', replace:true, props:['cur','all','pageNum'], methods:{ //页码点击事件 btnClick: f

  • 利用vue + element实现表格分页和前端搜索的方法

    前言 ElementUI是饿了么前端开源的一个基于Vue的前端框架,已经帮我们封装好了一系列功能性的组件,比如栅格系统.表格.表单.树形菜单.通知等.对于搞后台管理界面的项目,特别是不需要考虑兼容ie8.ie9以下的项目.ElementUI是一个不错的选择. 而且ElementUI的文档写得十分详尽,参照demo可以很快上手. 本文主要介绍了关于vue + element实现表格分页和前端搜索的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 实现思路 1.前端后台管理

  • Vue Cli与BootStrap结合实现表格分页功能

    1.首先需要在vue-cli项目中配置bootstrap,jquery 2. 然后新建vue文件,如index.vue,index.vue内容如下: 3.配置路由即可运行实现. <template> <div class="tTable container body-content"> <div class="form-group"> <div class="form-group"> <div

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

    前言 最近在做一个前后端分离的项目,前端使用 Vue+ Element UI,而后端则使用 Lumen 做接口开发,其中分页是必不可少的一部分,本文就介绍如何基于以上环境做一个简单.可复用的分页功能. 先说后端 后端做的事情不多,只需要接受几个参数,根据参数来获取数据即可. 需要获取的参数如下: pageSize(一页数据的数量) pageIndex(第几页的数据) 然后就可以根据这两个参数计算出偏移量,再从数据库中取出相应的数据. 假如现在给出的参数为:pageSize=10,pageInde

  • 基于Vue.js的表格分页组件

    一.Vue.js简介 1.Vue的主要特点: (1) 简洁 (2) 轻量 (3)快速 (4) 数据驱动 (5) 模块友好 (6) 组件化 (1) 简洁 下面看一段Angular的实现双向绑定的代码 // html <body ng-app="myApp"> <div ng-controller="myCtrl"> <p>{{ note }}</p> <input type="text" ng-

  • Vue2.0+ElementUI+PageHelper实现的表格分页功能

    前言 最近做了一些前端的项目,要对表格进行一些分页显示.表格分页的方法有很多,从宏观上来说分为物理分页和逻辑分页,由于逻辑分页(即前端分页)的做法是将数据全部缓存,然后分页显示,这样在数据量较大的时候会对浏览器的速度产生影响,所以考虑之后我使用了后端分页,后端分页的特点是对当前页的数据进行请求,每次当页码变化或者每页数据量变化的时候,就重新发一次请求.这里所用到的技术主要有以下几种: Spring SpringMVC Mybatis VueJS 2.0 ElementUI 后端数据库用的是Mys

  • vue2.0嵌套路由实现豆瓣电影分页功能(附demo)

    前言 最近练习Vue,看到官方文档中的嵌套路由,不做不知道,实在是太坑了,网上资料demo少之又少,然后自己就做了一个demo,用了vue2.0嵌套路由实现豆瓣电影分页功能,供大家学习学习,写得不好望见谅. demo截图: Demo简单介绍 主路由:Top250(charts),正在热映(hot),即将上映(ing),新片榜(newmovie) const router = new VueRouter({ routes: [ { path: '/', //设置默认路由为Top250 compon

  • 基于Vue2.0+ElementUI实现表格翻页功能

    Element UI 是一套采用 Vue 2.0 作为基础框架实现的组件库,它面向企业级的后台应用,能够帮助你快速地搭建网站,极大地减少研发的人力与时间成本.在这个月的 NingJS 上我们开源了这个项目,当时它的文档还没有准备好.今天,经过两周多的完善, Element UI 的文档正式上线啦!目前它处于 rc 阶段,正式版将于 Vue 2.0 发布后第一时间跟进. 欢迎大家来使用和完善,一起把它做成 Vue 最好的企业级组件库. ElementUI的表格要求的数据类型为字典数组.我使用了py

  • Vue2.0+ElementUI实现表格翻页的实例

    ElementUI的表格要求的数据类型为字典数组.我使用了python3写后端,那么从数据库取数据时添加一行cursorclass=pymysql.cursors.DictCursor即可.取出后我将其存入redis数据库方便之后取用.取用时使用eval()函数再传到前端即可. 前端放置Pagination 分页器,我这里直接采用了完整功能的分页器. <el-pagination @size-change="handleSizeChange" @current-change=&q

  • vue2.0结合DataTable插件实现表格动态刷新的方法详解

    本文实例讲述了vue2.0结合DataTable插件实现表格动态刷新的方法.分享给大家供大家参考,具体如下: 产品提出的需求是这样的,很普通的一个统计server端task完成率和状态的表格,要自动刷新其中的数据,并且当单个task完成的时候report给server端,看起来好easy好easy的一个需求啊!且听我说完哈! 我这边使用的是框架是vue,表格自然用v-for渲染,然后我们这边分页搜索神马的都是前端弄,也就是说后端只管把一大坨数据塞到前端,然后前端自己组装分页器和完成模糊搜索,所以

  • VUE2.0+Element-UI+Echarts封装的组件实例

    本文用Vue2.0+elementUI的panel组件和table组件+echarts的柱状图和折线图实现对结果的展示,实现了表格和图之间的切换和图和表之间的转置. -html <div class="resultDiv"> <div id="panels"> <el-collapse> <el-collapse-item v-for="item in indicators"> <templa

  • 解决vue2.0 element-ui中el-upload的before-upload方法返回false时submit()不生效问题

    我要实现的功能是在上传文件之前校验是否表格中存在重复的数据,有的话,需要弹窗提示是否覆盖,确认之后继续上传,取消之后,就不再上传. 项目中用的element-ui是V1.4.3 <el-upload class="upload-demo" drag ref="fileUpload" :action="urls.fileUpload" :on-success="handleUploadSuccess" :on-error=

  • 详解vue2.0的Element UI的表格table列时间戳格式化

    这两天学习了vue2.0的Element UI的表格table列时间戳格式化,所以,今天添加一点小笔记. 表格属性 <el-table :data="tableData" v-loading.body="loading" border @selection-change="selectionChange" style="width: 100%"> <el-table-column prop="cre

  • vue2.0 element-ui中el-select选择器无法显示选中的内容(解决方法)

    我使用的是element-ui V2.2.3.代码如下,当我选择值得时候,el-select选择器无法显示选中的内容,但是能触发change方法,并且能输出选择的值. select.vue文件 <template> <div> <div class="row" v-for="RowItem in rows"> <div class="col" v-for="colItem in RowItem.

  • php实现的后台表格分页功能示例

    本文实例讲述了php实现的后台表格分页功能.分享给大家供大家参考,具体如下: <?php //init.php $conn = mysqli_connect('127.0.0.1','root','','xz',3306); $sql = "SET NAMES UTF8"; mysqli_query($conn,$sql); $pagecount = 3; ?> user.php: <?php //用户管理 echo "用户管理<br/>&quo

随机推荐