vue開發分頁組件

組件效果圖

在這裏插入圖片描述

組件用法

<pagination
    :show-jumper="true"
    :total="100"
    :currentPage="20"
    :pagerCount="7"
    @prev-click="prevClick"
    @next-click="nextClick"
    @prev-quick-click="prevQuickClick"
    @next-quick-click="nextQuickClick"
    @page-click="pageClick"
    @current-change="currentChange"
    @jumpe="pageJumpe"
/>
<script>
	methods: {
	    prevClick(page) {
	        console.log('上一頁', page);
	    },
	    nextClick(page) {
	        console.log('下一頁', page);
	    },
	    pageClick(page) {
	        console.log('分頁點擊', page);
	    },
	    pageJumpe(page) {
	        console.log('跳轉', page);
	    },
	    prevQuickClick(page) {
	        console.log('快速向前切換', page);
	    },
	    nextQuickClick(page) {
	        console.log('快速向後切換', page);
	    },
	    currentChange(page, old) {
	        console.log('分頁切換', page, '切換前分頁', old);
	    }
	}
</script>

組件代碼

<template>
    <div class="pagination" :class="{' pagination-vertical' : mode ==='vertical'}">
        <button type="button" :disabled="current === 1" class="btn-prev" @click="prevPage">
            <i class="iconfont icon-arrow-left"></i>
        </button>
        <ul class="pager">
            <li
                v-for="(page, index) in pageList"
                :class="{
                    active: page === current && typeof page !== 'string', 
                    'more btn-quickprev': page === 'prev',
                    'more btn-quicknext': page === 'next'
                    }"
                @click="pagerClick(page)"
            >{{typeof page === 'number' ? page + suffix : '•••'}}</li>
        </ul>
        <button type="button" :disabled="current === total" class="btn-next" @click="nextPage">
            <i class="iconfont icon-arrow-right"></i>
        </button>
        <span class="go-page" v-if="showJumper && mode ==='horizontal'">
            前往&thinsp;
            <input
                ref="goPageInput"
                type="text"
                @blur="goPage($refs.goPageInput.value*1)"
            />&thinsp;</span>
    </div>
</template>

<script>
export default {
    name: 'pagination',
    props: {
        //總頁數
        total: {
            type: Number,
            default: 30
        },
        //當前頁
        currentPage: {
            type: Number,
            default: 1
        },
        //頁碼顯示數量
        pagerCount: {
            type: Number,
            default: 7
        },
        //展示模式橫向或豎向
        mode: {
            type: String,
            default: 'horizontal'
        },
        //分頁跳轉
        showJumper: {
            type: Boolean,
            default: false
        },
        //分頁碼後綴
        suffix: {
            type: String,
            default: ''
        }
    },

    data() {
        return {
            current: 1,
            pageList: [] //分頁列表
        };
    },
    watch: {
        total() {
            this.getPageList(this.current);
        },
        currentPage(val) {
            this.current = val;
        },
        pagerCount() {
            this.getPageList(this.current);
        },
        current(val, old) {
            this.pageList = this.getPageList(val);
            this.$emit('current-change', val, old);
        }
    },
    mounted() {
        this.current = this.currentPage;
        this.pageList = this.getPageList(this.current);
    },
    methods: {
        getPageList(current) {
            let { total, pagerCount } = this;
            let pageList = [];
            //如果總頁數在可顯示頁碼數量以內,全部顯示
            if (pagerCount > total - 1) {
                for (let i = 1; i <= total; i++) {
                    pageList.push(i);
                }
            } else {
                //如果總頁數超過可顯示頁碼數量,根據不同情況顯示

                //當前頁能連到開始
                if (current < pagerCount - 1) {
                    for (let i = 1; i < pagerCount; i++) {
                        pageList.push(i);
                    }
                    pageList.push('next');
                    pageList.push(total);
                } else {
                    //當前頁能連到結束
                    if (current >= total - 1 - Math.floor(pagerCount / 2)) {
                        pageList.push(1);
                        pageList.push('prev');
                        for (
                            let i = total - (pagerCount - 2);
                            i <= total;
                            i++
                        ) {
                            pageList.push(i);
                        }
                    } else {
                        //當前頁不能連到結束
                        pageList.push(1);
                        pageList.push('prev');

                        for (
                            let i = current - Math.floor((pagerCount - 2) / 2);
                            i <=
                            current + (Math.ceil((pagerCount - 2) / 2) - 1);
                            i++
                        ) {
                            pageList.push(i);
                        }

                        pageList.push('next');
                        pageList.push(total);
                    }
                }
            }

            return pageList;
        },
        /**
         * 上一頁
         */
        prevPage() {
            if (this.current > 1) {
                this.current--;

                this.$emit('prev-click', this.current);
            }
        },
        /**
         * 下一頁
         */
        nextPage() {
            if (this.current < this.total) {
                this.current++;
                this.$emit('next-click', this.current);
            }
        },
        /**
         * 分頁點擊
         * @param {Number} page 目標頁面
         */
        pagerClick(page) {
            if (typeof page === 'number') {
                this.current = page;
                this.$emit('page-click', page);
            } else {
                let quickPage = 1;
                if (page === 'prev') {
                    quickPage = this.current - (this.pagerCount - 2);
                    quickPage < 1 && (quickPage = 1);
                }

                if (page === 'next') {
                    quickPage = this.current + (this.pagerCount - 2);
                    quickPage > this.total && (quickPage = this.total);
                }
                this.current = quickPage;

                this.$emit(`${page}-quick-click`, this.current);
            }
        },
        /**
         * 跳轉頁
         * @param {Number} page 目標頁面
         */
        goPage(page) {
            this.current = page < 1 ? 1 : page > this.total ? this.total : page;
            this.$refs.goPageInput.value = this.current;

            this.$emit('jumpe', page);
        }
    }
};
</script>

<style lang="scss" scoped>
.pagination {
    &,
    & * {
        box-sizing: border-box;
    }
    display: flex;
    min-height: 32px;
    border-radius: 2px;
    background-color: #fff;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);

    .pager {
        display: flex;
        margin: 0;
        padding: 0;

        li {
            list-style: none;
            color: #606266;
            &:not(.disabled).active {
                color: #fff;
                background-color: #409eff;
                pointer-events: none;
                cursor: none;
            }
            &:hover {
                color: #409eff;
            }
        }
        .more {
            color: #999;
        }
    }

    .pager li,
    .btn-next,
    .btn-prev {
        min-width: 32px;
        height: 32px;
        line-height: 32px;
        font-size: 12px;
        text-align: center;
        background-color: #fff;
        cursor: pointer;
        user-select: none;
    }

    button {
        display: block;
        border: 0;
        font-weight: 600;
        color: #888;
        vertical-align: top;

        &:focus {
            outline: none;
            border: none;
        }
        &[disabled] {
            color: #c0c4cc;
            cursor: not-allowed;
        }
    }
    .btn-prev {
        border-bottom-left-radius: 2px;
        border-bottom-right-radius: 2px;
    }

    .btn-next {
        border-top-left-radius: 2px;
        border-top-right-radius: 2px;
    }
    .go-page {
        height: 32px;
        line-height: 32px;
        font-size: 12px;
        margin-right: 10px;
        input {
            width: 40px;
            height: 22px;
            line-height: 20px;
            border: 1px solid #ddd;
            border-radius: 4px;
            color: #606266;
            text-align: center;
            &:focus {
                outline: none;
            }
        }
    }
}

.pagination-vertical {
    flex-direction: column-reverse;

    .pager {
        flex-direction: column-reverse;
    }

    button {
        transform: rotate(-90deg);
    }

    .btn-prev {
        border-top-left-radius: 2px;
        border-bottom-right-radius: 0;
    }

    .btn-next {
        border-top-left-radius: 0;
        border-bottom-right-radius: 2px;
    }
}
</style>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章