vue学习系列-完成一个分页组件的封装

分页是我们前端开发中经常要用到的一个组件,也有很多人提供了这样的组件,比如jquery.page.js、layer等等,都比较好用,几天我们就自己用vue来撸一个page组件,首先先来看看最终完成的效果

vue page

就是一个这样的,很简单的组件。

老规矩,先看下html结构

<div class="page-box">
        <a href="javascript:;" :data-page="currPage - 1" v-if="hasPre" @click="goPre()">上一页</a>
        <a href="javascript:;" data-page="1" title="首页" v-if="hasHome" @click="goPage(1)">首页</a>
        <span v-if="hasFirstDot"></span>
        <a href="javascript:;" v-for="(item, index) in pageData" :data-page="item" :class="{'page-curr': item == currPage}" @click="changePage(index, item)">{{item}}</a>
        <span v-if="hasLastDot"></span>
        <a href="javascript:;" class="page-last" title="尾页" :data-page="pageTotal" v-if="hasLast" @click="goPage(pageTotal)">末页</a>
        <a href="javascript:;" class="page-next" :data-page="currPage+1" v-if="hasNext" @click="goNext()">下一页</a>
        <span class="page-total">
            到第
            <input type="number" min="1" v-model="toPage"><button type="button" @click="goPage(toPage)">确定</button>
        </span>
    </div>

从结构可以看出,我们用到几个boolean变量来控制按钮的显示,这也是vue的优势所在,我们不用写一个很长的function的来判断要怎么生成html代码,最后push到节点内。
这几个变量分别是

hasPre: false,      //控制下一页按钮显示
hasNext: true,      //控制上一页按钮显示
hasHome: false,     //控制首页按钮显示
hasLast: true,      //控制末页按钮显示
hasFirstDot: false, //控制第一个省略点显示
hasLastDot: true,   //控制第二个省略点显示

每次点击都重新通过一个createData的方法来生成新的显示页码

createData (page) {
    var data = [];
    //两种极端
    if(page - this.prifix <= 0 && this.pageTotal < 5){
        for (var i = 0; i < this.pageTotal; i++) {
            data.push(i + 1)
        }
        return data;
    }

    if(page + this.prifix >= this.pageTotal){
        for (var i = this.pageTotal; i > this.pageTotal - 5; i--) {
            data.push(i)
        }
        return data.reverse();
    }

    var left = [],right = [];
    var ix = 1;

    if(page < 5){
        for(var i=1; i < page; i++){
            var temp = page - ix
            if(temp <= 0) break;
            left.push(temp)
            ix ++
        }
    }else{
        for(var i=page-2; i < page; i++){
            var temp = page - ix
            if(temp <= 0) break;
            left.push(temp)
            ix ++
        }
    }
    left.reverse()
    left.push(page)
    if(page < 5){
        var idx = 1;
        for(var j=page; j < 5; j++){
            var temp_right = page + idx
            right.push(temp_right)
            idx ++
        }
    }else{
        var idx = 1;
        for(var j=page; j < page + this.prifix; j++){
            var temp_right = page + idx
            right.push(temp_right)
            idx ++
        }
    }

    left.push.apply(left,right); //合并数组
    return left;
}

并且通过一个checkSpan方法来控制是否显示各个按钮,

checkSpan(){
    if(this.currPage >= 2){
        this.hasPre = true
    }else{
        this.hasPre = false
    }
    if(this.currPage >= 5){
        this.hasHome = true
        this.hasFirstDot = true
    }else{
        this.hasHome = false
        this.hasFirstDot = false
    }
    if(this.currPage >= this.pageTotal - this.prifix){
        this.hasLast = false
        this.hasLastDot = false
    }else{
        this.hasLast = true
        this.hasLastDot = true
    }
    if(this.currPage <= this.pageTotal - 1){
        this.hasNext = true
    }else{
        this.hasNext = false
    }
}

有了这两核心的方法这个功能已经完成大半。
下面是所有的javascript逻辑控制代码

export default {
        data () {
            return {
                pageData: [],
                currPage: 1,
                hasPre: false,
                hasNext: true,
                hasHome: false,
                hasLast: true,
                hasFirstDot: false,
                hasLastDot: true,
                // pageTotal: 50,
                prifix: 2,
                toPage: 1,
            }
        },
        props: ['pageTotal', 'curr'],
        created: function () {
            this.pageData = this.createData(1)
            this.checkSpan()
            this.currPage = this.curr;
        },
        methods: {
            changePage (index, item) {
                this.currPage = this.pageData[index]
                this.toPage = this.pageData[index]
                this.checkSpan(index)
                this.pageData = this.createData(this.currPage)
                this.$emit('pageChange', index, item);
            },
            goPre () {
                var key = this.getKeyFromArr(this.pageData, this.currPage)
                this.changePage(key*1 -1, this.currPage)
            },
            goNext () {
                var key = this.getKeyFromArr(this.pageData, this.currPage)
                this.changePage(key*1 + 1, this.currPage)
            },
            goPage (page) {
                var key = this.getKeyFromArr(this.pageData, page)
                if(key !== -1){
                    this.changePage(key, page)
                }else{
                    //没有
                    if(page > this.pageTotal) return;
                    this.currPage = page
                    this.toPage = page
                    this.pageData = this.createData(page * 1)
                    this.checkSpan()
                    var key = this.getKeyFromArr(this.pageData, this.currPage)
                    this.$emit('pageChange', key, page);
                }
            },
            checkSpan(){
                if(this.currPage >= 2){
                    this.hasPre = true
                }else{
                    this.hasPre = false
                }
                if(this.currPage >= 5){
                    this.hasHome = true
                    this.hasFirstDot = true
                }else{
                    this.hasHome = false
                    this.hasFirstDot = false
                }
                if(this.currPage >= this.pageTotal - this.prifix){
                    this.hasLast = false
                    this.hasLastDot = false
                }else{
                    this.hasLast = true
                    this.hasLastDot = true
                }
                if(this.currPage <= this.pageTotal - 1){
                    this.hasNext = true
                }else{
                    this.hasNext = false
                }
            },

            createData (page) {
                var data = [];
                //两种极端
                // if(page -1 < 0 || page+1 > this.pageTotal) return this.pageData;
                if(page - this.prifix <= 0 && this.pageTotal < 5){
                    for (var i = 0; i < this.pageTotal; i++) {
                        data.push(i + 1)
                    }
                    return data;
                }

                if(page + this.prifix >= this.pageTotal){
                    for (var i = this.pageTotal; i > this.pageTotal - 5; i--) {
                        data.push(i)
                    }
                    return data.reverse();
                }

                var left = [],right = [];
                var ix = 1;

                if(page < 5){
                    for(var i=1; i < page; i++){
                        var temp = page - ix
                        if(temp <= 0) break;
                        left.push(temp)
                        ix ++
                    }
                }else{
                    for(var i=page-2; i < page; i++){
                        var temp = page - ix
                        if(temp <= 0) break;
                        left.push(temp)
                        ix ++
                    }
                }
                left.reverse()
                left.push(page)
                if(page < 5){
                    var idx = 1;
                    for(var j=page; j < 5; j++){
                        var temp_right = page + idx
                        right.push(temp_right)
                        idx ++
                    }
                }else{
                    var idx = 1;
                    for(var j=page; j < page + this.prifix; j++){
                        var temp_right = page + idx
                        right.push(temp_right)
                        idx ++
                    }
                }

                left.push.apply(left,right); //合并数组
                return left;
            },
            getKeyFromArr (arr, val) {
                var key = -1;
                for(var k in arr){
                    if(arr[k] == val){
                        key = k 
                    }
                }
                return key
            }
        }
    }

最后我们给他加一点样式,就大功告成了

.page-box{
        -webkit-box-sizing: content-box!important;
        -moz-box-sizing: content-box!important;
        box-sizing: content-box!important;
        display: inline-block;
        vertical-align: middle;
        margin: 10px 0;
        font-size: 0;
    }
    .page-box span,.page-box a{
        display: inline-block;
        vertical-align: middle;
        padding: 0 15px;
        border: 1px solid #e2e2e2;
        height: 28px;
        line-height: 28px;
        margin: 0 -1px 5px 0;
        background-color: #fff;
        color: #333;
        font-size: 12px;
        color: #999;
        font-weight: 700;
    }
    .page-box .page-curr{
        background-color: #009688;
        color: #fff;
        font-weight: 400;
        text-align: center;
        font-style: normal;
    }
    .page-box>:first-child, .page-box>:first-child em {
        border-radius: 2px 0 0 2px;
    }
    .page-box .page-total {
        height: 30px;
        line-height: 30px;
        margin-left: 1px;
        border: none;
        font-weight: 400;
    }
    .page-box input,.page-box button {
        height: 30px;
        line-height: 30px;
        border: 1px solid #e2e2e2;
        border-radius: 2px;
        vertical-align: top;
        background-color: #fff;
        box-sizing: border-box!important;
        width: 50px;
        margin: 0 5px;
        text-align: center;
    }

接下来我们看怎么调用这个组件
我们只要在script里写下

import page from 你的路径

在components里写下

components: {
            page
        }

就成功的调用组件了,
完整的调用代码如下

<template>
    <div id="demo5">
        <page :pageTotal="total" :curr="currPage" v-on:pageChange="pageChange"></page>
    </div>
</template>
<script type="text/javascript">
    import page from '../../components/Page/index.vue'
    export default {
        data () {
            return {
                total: 15,
                currPage: 2
            }
        },
        methods: {
            pageChange (index, item) {
                console.info('触发',index, item)
            }
        },
        components: {
            page
        }
    }
</script>

组件git地址:传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雪月青

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值