你的位置:首页 > Java教程

[Java教程]vue分页组件table


  之前一直接触都是原始的前端模型,jquery+bootstrap,冗杂的dom操作,繁琐的更新绑定。接触vue后,对前端MVVM框架有了全新的认识。本文是基于webpack+vue构建,由于之前的工作主要是基于java的服务端开发工作,对前端框架和组件的理解,不够深入,借此来记录在前端框架使用和构建中的点点滴滴。

  此分页组件参照于bootstrap-datatable底部分页开发完成,相关参数增加自定义功能。

  最终使用展现效果图如下,数据来源于cnodejs【https://cnodejs.org/】

  底部分页组件主要由左侧当前数据项数量显示和右侧分页页码两部分组成。组件代码如下:

<template      -bind="http://www.w3.org/1999/xhtml">  <div >    <div >      <div>        <select v-on:change="menuChange()" v-model="limit">          <option v-for="item in menu" v-bind:value="item">{{item}}</option>        </select>        记录/页,显示第 {{start}} 至 {{end}} 项记录,共 {{totalSize}} 项      </div>    </div>    <div >      <ul>        <li><a v-on:click="firstClick()" v-bind:>首页</a></li>        <li><a v-on:click="preClick()" v-bind:>上一页</a></li>        <li v-for="per in pages" v-bind:>          <a v-on:click="pageClick(per)">{{ per }}</a>        </li>        <li><a v-on:click="nextClick()" v-bind:>下一页</a></li>        <li><a v-on:click="lastClick()" v-bind:>尾页</a></li>        <li><a>共<i>{{totalPage}}</i>页</a></li>      </ul>    </div>    <div ></div>  </div></template><script>  import Ajax from '../ajax'  export default{    props: ['page-model'],    data () {      return {        // 初始页        cur: 1,        // 请求地址        url: this.pageModel.url ? this.pageModel.url : "",        // 请求参数        param: this.pageModel.param ? this.pageModel.param : {},        // 请求方法 默认为GET请求        method: this.pageModel.method ? this.pageModel.method : 'GET',        // 每页显示数量 默认每页显示10条        limit: this.pageModel.menu ? this.pageModel.menu[0] : 10,        // 底部分页基数 默认5        perSize: this.pageModel.perSize ? this.pageModel.perSize : 5,        // 每页显示数量 下拉选项        menu: this.pageModel.menu ? this.pageModel.menu : [5, 10, 50],        // 分页参数 自定义名称        pageParamName: this.pageModel.pageParamName ? this.pageModel.pageParamName : ['page', 'limit'],        // 当前列表显示记录起始数        start: 0,        // 当前列表显示记录结束数        end: 0,        // 总页数        totalPage: 0,        // 记录总数        totalSize: 0,        // 分页请求返回数据        dataList: []      }    },    ready () {      this.getData();    },    methods: {      // 首页      firstClick: function () {        if (this.cur > 1) {          this.cur = 1;          this.getData();        }      },      // 尾页      lastClick: function () {        if (this.cur < this.totalPage) {          this.cur = this.totalPage;          this.getData();        }      },      // 上一页      preClick: function () {        if (this.cur > 1) {          this.cur--;          this.getData();        }      },      // 下一页      nextClick: function () {        if (this.cur < this.totalPage) {          this.cur++;          this.getData();        }      },      // 页码      pageClick: function (data) {        if (data != this.cur) {          this.cur = data;          this.getData();        }      },      // 刷新显示记录数      refreshPageCon: function () {        this.start = (this.cur - 1) * this.limit + 1;        if (this.totalSize >= this.limit * this.cur) {          this.end = this.limit * this.cur;        } else {          this.end = this.totalSize;        }      },      // 分页请求      getData: function () {        let _this = this;        this.param[this.pageParamName[0]] = this.cur;        this.param[this.pageParamName[1]] = this.limit;        Ajax({          url: _this.url,          method: _this.method,          data: _this.param,          callback: function (res) {            // 返回结果数据集            this.dataList = res.data;            // 返回总记录数            _this.totalSize = 25;            _this.totalPage = Math.ceil(_this.totalSize / _this.limit);            _this.refreshPageCon();            _this.$dispatch('refresh', this.dataList);          }        });      },      // 每页显示记录数 下拉      menuChange: function () {        this.getData();      },      getPage: function (curPage, totalPage, pageNum) {        var leftPage, rightPage;        curPage = curPage > 1 ? curPage : 1;        curPage = curPage > totalPage ? totalPage : curPage;        totalPage = curPage > totalPage ? curPage : totalPage;        // 左侧页数        leftPage = curPage - Math.floor(pageNum / 2);        leftPage = leftPage > 1 ? leftPage : 1;        // 右侧页数        rightPage = curPage + Math.floor(pageNum / 2);        rightPage = rightPage > totalPage ? totalPage : rightPage;        var curPageNum = rightPage - leftPage + 1;        // 左侧调整        if (curPageNum < pageNum && leftPage > 1) {          leftPage = leftPage - (pageNum - curPageNum);          leftPage = leftPage > 1 ? leftPage : 1;          curPageNum = rightPage - leftPage + 1;        }        // 右侧调整        if (curPageNum < pageNum && rightPage < totalPage) {          rightPage = rightPage + (pageNum - curPageNum);          rightPage = rightPage > totalPage ? totalPage : rightPage;        }        var arr = [];        for (var i = leftPage; i <= rightPage; i++) {          arr.push(i);        }        return arr;      }    },    computed: {      pages: function () {        return this.getPage(this.cur, this.totalPage, this.perSize);      }    }  }</script><style>  ul, li {    margin: 0px;    padding: 0px;  }  li {    list-style: none;    display: inline;  }  .page-bar li:first-child > a {    margin-left: 0px  }  .page-bar a {    border: 1px solid #ddd;    text-decoration: none;    position: relative;    float: left;    padding: 6px 12px;    margin-left: -1px;    line-height: 1.42857143;    color: #337ab7;    cursor: pointer;  }  .page-bar a:hover {    background-color: #eee;  }  .page-bar .active a {    color: #fff;    cursor: default;    background-color: #337ab7;    border-color: #337ab7;  }  .page-bar i {    font-style: normal;    color: #d44950;    margin: 0px 4px;    font-size: 12px;  }  .page-bar .page-con, .page-size {    width: 50%;    display: block;    height: 30px;    float: left;    line-height: 30px;  }  .page-bar .page-con ul {    float: right;    padding-left: 15px;    padding-right: 15px;    display: inline-block;    padding-left: 0;  }  .page-bar .page-size div {    padding-left: 15px;    padding-right: 15px;    font-size: 14px;  }  a.disabled {    color: #777;    background-color: #fff;    border-color: #ddd;    cursor: not-allowed;  }  a.disabled:hover {    background-color: #fff;  }  .clear-both {    clear: both;  }  select {    border: solid 1px #ddd;    appearance: none;    -moz-appearance: none;    -webkit-appearance: none;    background: url("../assets/images/arrow.png") no-repeat scroll right center transparent;    padding-right: 15px;    padding-left: 15px;    padding-top: 2px;    padding-bottom: 2px;  }  select::-ms-expand {    display: none;  }</style>

  组建模块使用,

<template>  <Navbar></Navbar>  <div >    <table >      <thead>      <tr>        <th>标题</th>        <th width="20%">发布时间</th>        <th width="10%">作者</th>        <th width="10%">回复数</th>        <th width="10%">访问数</th>      </tr>      </thead>      <tbody>      <tr v-show="!tabelEmpty" v-for="item in dataList">        <td>{{item.title}}</td>        <td>{{item.create_at}}</td>        <td>{{item.author.loginname}}</td>        <td>{{item.reply_count}}</td>        <td>{{item.visit_count}}</td>      </tr>      <tr v-show="tabelEmpty" >        <td colspan="5">没有匹配的记录</td>      </tr>      </tbody>    </table>  </div>  <Pagebar :page-model="pageModel"></Pagebar></template><script>  import Navbar from '../components/navbar.vue'  import Pagebar from '../components/table-pagebar.vue'  export default {//这里是官方的写法,默认导出,ES6    components: {      Navbar,      Pagebar    },    data () {      return {        allArticle: "",        dataList: [],        pageModel: {          url: 'https://cnodejs.org/api/v1/topics',          menu: [5, 10, 20]        },      }    },    computed: {      tabelEmpty: function () {        if (this.dataList) {          return false;        } else {          return true;        }      }    },    events: {      refresh: function (e) {        this.dataList = e;      }    }  }</script><style>  body, table {    font-size: 12px;  }  table {    table-layout: fixed;    empty-cells: show;    border-collapse: collapse;    width: 100%;    margin: 10px 0;  }  td {    height: 30px;  }  div.row {    margin-left: 15px;    margin-right: 15px;  }  h1, h2, h3 {    font-size: 12px;    margin: 0;    padding: 0;  }  .table {    border: 1px solid #ddd;    background: #fff;  }  .table thead tr {    background: #eee;  }  .table th {    background-repeat: repeat-x;    height: 30px;    text-align: left;    vertical-align: middle;  }  .table tr.empty {    text-align: center;  }  .table td, .table th {    border: 1px solid #ddd;    padding: 0 1em 0;  }  .table tr:nth-child(odd) td {    background-color: #f5f5f5;  }</style>

 

作者:江南久无雪
源码下载:http://git.oschina.net/leeckent/vue-code
声明:原创博客请在转载时保留原文链接或者在文章开头加上本人博客地址,如发现错误,欢迎批评指正。