JavaScript

超轻量级php框架startmvc

一个可复用的vue分页组件

更新时间:2020-05-12 03:30:01 作者:startmvc
不废话,先上组件文件pages.vue:<template><divclass="pages-box"v-if="pageTotal>0"><ulclass="pa

不废话,先上组件文件pages.vue:


<template>
 <div class="pages-box" v-if="pageTotal > 0">
 <ul class="pages">
 <li class="pages-prev">
 <a v-if="pageNow != 1" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="prevClick">上一页</a>
 </li>
 <!--如果只有一页就不显示固定的第一个分页按钮了,避免重复-->
 <template v-if="pageTotal > 1">
 <li v-for="i in pageBegin" class="pages-li" :class="{active:i == pageNow}">
 <span v-if="i == pageNow" v-text="i"></span>
 <a v-else href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="pageClick" v-text="i"></a>
 </li>
 </template>
 <li v-if="ellipsis[0] > slider">
 <span>...</span>
 </li>
 <li v-for="i in pageMiddle" class="pages-li" :class="{active:i == pageNow}">
 <span v-if="i == pageNow" v-text="i"></span>
 <a v-else href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="pageClick" v-text="i"></a>
 </li>
 <li v-if="pageTotal - ellipsis[1] > slider">
 <span>...</span>
 </li>
 <li v-for="i in pageEnd" class="pages-li" :class="{active:i == pageNow}">
 <span v-if="i == pageNow" v-text="i"></span>
 <a v-else href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="pageClick" v-text="i"></a>
 </li>

 <li class="pages-next">
 <a v-if="pageNow != pageTotal" href="javascript:void(0);" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" @click="nextClick">下一页</a>
 </li>
 </ul>
 </div>
</template>

<script>
 export default{
 name: 'pages',
 props: {
 //总页数
 total: {
 type: [Number, String],
 required: true
 },
 //当前页
 now: {
 type: [Number, String],
 default: 1
 }
 },
 data() {
 return {
 //当前页
 pageNow: this.now,
 //总页数
 pageTotal: this.total,
 //输入的页码
 pageNum: "",
 //显示分页按钮的个数
 length: 8,
 //前后固定的分页按钮个数
 slider: 1
 }
 },
 watch: {
 total(val){
 let page_total = parseInt(val);
 page_total = (isNaN(page_total) || page_total < 1) ? 1 : page_total;
 this.pageTotal = page_total;
 },
 now(val){
 let page_now = parseInt(val);
 page_now = (isNaN(page_now) || this.pageTotal < 2 || page_now < 1) ? 1 : page_now;
 page_now = page_now > this.pageTotal ? this.pageTotal : page_now;
 this.pageNow = page_now;
 }
 },
 computed: {
 //前边显示固定分页数
 pageBegin(){
 return Math.min(this.slider, this.ellipsis[0]);
 },
 //中间显示分页数
 pageMiddle(){
 let arr = [];
 for (let i = this.ellipsis[0] + 1; i <= this.ellipsis[1]; i++) {
 arr.push(i);
 }
 return arr;
 },
 //后边显示分页数
 pageEnd(){
 let arr = [];
 for (let i = this.ellipsis[2] + 1; i <= this.pageTotal; i++) {
 arr.push(i);
 }
 return arr;
 },
 /**
 * 出现三个点时的分页的范围
 * @returns {*[]}
 * begin: 开始页码
 * end: 结束页码
 * end_max: 结束页码的最大值
 */
 ellipsis() {
 let end_max = this.pageTotal - this.slider;
 let begin = this.pageNow - (this.length / 2) + this.slider;
 begin = begin < 1 ? 1 : begin;
 let end = begin + this.length - 2 * this.slider;
 //当begin达到最小值后需要根据begin重新计算end以保证显示的分页按钮个数不变
 end = begin < this.slider ? (end + this.slider - begin) : end;
 if (end >= end_max) {
 end = end_max;
 //当end达到最大值后需要根据end重新计算begin以保证显示的分页按钮个数不变
 begin = (end - this.length + 2 * this.slider) < 1 ? 1 : (end - this.length + 2 * this.slider);
 }
 return [begin, end, end_max];
 }
 },
 methods: {
 //上一页
 prevClick() {
 this.pageNow--;
 this.pageNow = this.pageNow < 1 ? 1 : this.pageNow;
 this.changePage(this.pageNow);
 },
 //下一页
 nextClick() {
 this.pageNow++;
 this.pageNow = this.pageNow > this.pageTotal ? this.pageTotal : this.pageNow;
 this.changePage(this.pageNow);
 },
 //点击页码
 pageClick(e) {
 this.pageNow = Number(e.target.innerText.trim());
 this.changePage(this.pageNow);
 },
 //输入页码
 pageInput(e){
 let num = parseInt(e.target.innerText);
 if(isNaN(num)){
 this.pageNum = '';
 e.target.innerText = '';
 } else {
 this.pageNum = num;
 //e.target.innerText = num;
 }
 },
 //跳转到输入的页码
 goClick() {
 this.pageNum = this.pageNum < 1 ? 1 : this.pageNum;
 this.pageNum = this.pageNum > this.pageTotal ? this.pageTotal : this.pageNum;
 this.pageNow = this.pageNum;
 this.pageNum = "";
 this.changePage(this.pageNow);
 },
 // 切换分页
 changePage(page){
 let {name, params, query} = this.$route;
 this.$router.push({
 name,
 params: Object.assign(params, {page}),
 query
 });
 }
 }
 }
</script>
<style lang="sass" type="text/scss" rel="stylesheet/scss">
 @import '../scss/base/variables';

 .pages-box{
 position: relative;
 padding: 5px 10px;
 margin: 20px 0;
 text-align: center;
 }

 .pages{
 display: inline-block;
 padding: 10px 0;
 &:after{
 content: "";
 display: table;
 line-height: 0;
 clear: both;
 }
 li{
 float: left;
 height: 20px;
 line-height: 20px;
 text-align: center;
 margin: 0 2px;
 box-sizing: border-box;
 font-size: 13px;
 span, a{
 display: block;
 width: 100%;
 height: 100%;
 padding: 0 2px;
 box-sizing: border-box;
 }
 }
 .pages-li{
 min-width: 30px;
 border: 1px solid $theme;
 color: $theme;
 a{
 color: $theme;
 }
 &.active{
 span{
 background: $theme;
 color: #fff;
 }
 }
 }
 .pages-prev, .pages-next{
 padding: 0 8px;
 font-size: 12px;
 a{
 display: block;
 height: 100%;
 position: relative;
 color: $theme;
 &:before{
 content: '';
 position: absolute;
 top: 50%;
 display: block;
 width: 6px;
 height: 6px;margin-top:-4px;
 border-left: 1px solid $theme;
 border-top: 1px solid $theme;
 }
 }
 }
 .pages-prev a{
 padding-left: 8px;
 &:before{
 transform:rotate(-45deg);
 left: 0;
 }
 }
 .pages-next a{
 padding-right: 8px;
 &:before{
 transform:rotate(135deg);
 right: 0;
 }
 }
 .pages-num{
 .num-input{
 min-width: 20px;
 height: 20px;
 padding: 0 5px;
 line-height: 20px;
 border-radius: 2px;
 border: 1px solid $theme;
 color: $theme;
 text-align: center;
 outline: none;
 }
 }
 .pages-go{
 a{
 color: $theme;
 }
 span{
 color: #666;
 }
 }
 }
</style>

使用方法:

在需要分页的地方使用分页组件标签,比如这里的order.vue:


<!--分页组件-->
<pages :now="page" :total="totalPage" v-if="totalPage > 0"></pages>

在data中设置当前页和总页面的默认值


data(){
 return {
 totalPage:1,
 page:1,
 }
 },

考虑一下我们希望我们点击页数按钮后发生什么

首先,点击某页数时路由会改变页数,从路由获取当前页


this.page = this.$route.params.page;

接着,我们希望有一个getorderfromServer方法将当前页数发送给服务器,再将返回的数据更新在页面上


getorderfromServer({
 currentPage:this.page
 })

最后调用的方法:


methods: {
 // 查询全部订单
 getorderfromServer(){
 this.loading = true;
 this.page = this.$route.params.page;
 getorderfromServer({
 currentPage: this.page,
 orderTimeStart:this.orderTimeStart,
 orderTimeEnd:this.orderTimeEnd,
 serviceName:this.serviceName,
 shopName:this.shopName,
 status: this.status
 }).then(({code, data}) => {
 if (code == 200) {
 this.Orderlist = data.list;
 this.totalPage = data.totalPage;
 }
 this.loading = false;
 }).catch(err => {
 this.tip('服务内部错误', 'error');
 this.Orderlist = {};
 this.loading = false;
 });
 },
 }

注意通过路由对方法作出响应,每次路由改变都调用此方法以更新页面


watch: {
 $route: 'getorderfromServer'
 }

还要对路由信息进行改造,让每一页(尤其是第一页)都有路由页数信息,可以对第一页进行重定向以达到目的:


{
 path: 'order',
 redirect: 'order/page/1',
},
{
 path: 'order/page/:page',
 component(resolve){
 require.ensure([], function (require) {
 resolve(require('../modules/personal/order/myorder.vue'));
 }, 'modules/personal')
 },
 name:'order',
 meta: {
 login: 'none'
 }
},

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

vue 分页组件