Vue组件设计-表单分页

2023-05-03 09:30:35 浏览数 (1)

表单分页在后台管理系统中最为常见,几乎所有的表格页面都会用到,但是一般的UI框架分页组件在点击切换分页后,都没有自动滚动置顶的功能,为了更好的用户体验以及全局复用,有必要自己封装一个分页组件。

1. 组件的基本封装

代码语言:javascript复制
<template>
    <div :class="{ hidden: hidden }" class="pagination-container">
        <el-pagination
            :total="total"
            v-bind="$attrs"
            :layout="layout"
            :page-sizes="pageSizes"
            :background="background"
            :page-size.sync="pageSize"
            @size-change="handleSizeChange"
            :current-page.sync="currentPage"
            @current-change="handleCurrentChange"
        />
    </div>
</template>

<script>

import { scrollTo } from "@/utils/scroll-to";

export default {
    name: "Pagination",
    props: {
        total: {
            required: true,
            type: Number,
        },
        page: {
            type: Number,
            default: 1,
        },
        limit: {
            type: Number,
            default: 20,
        },
        pageSizes: {
            type: Array,
            default() {
                return [10, 20, 30, 50];
            },
        },
        layout: {
            type: String,
            default: "total, sizes, prev, pager, next, jumper",
        },
        background: {
            type: Boolean,
            default: true,
        },
        autoScroll: {
            type: Boolean,
            default: true,
        },
        hidden: {
            type: Boolean,
            default: false,
        },
    },
    computed: {

        currentPage: {

            get() {
                return this.page;
            },
            set(val) {
                this.$emit("update:page", val);
            },

        },

        pageSize: {

            get() {
                return this.limit;
            },
            set(val) {
                this.$emit("update:limit", val);
            },

        },

    },
    methods: {

        handleSizeChange(val) {
            this.$emit("pagination", { page: this.currentPage, limit: val });
            if (this.autoScroll) {
                scrollTo(0, 800);
            }
        },

        handleCurrentChange(val) {
            this.$emit("pagination", { page: val, limit: this.pageSize });
            if (this.autoScroll) {
                scrollTo(0, 800);
            }
        },

    },
};
</script>

<style scoped>
.pagination-container {
    background: #fff;
    padding: 32px 16px;
}
.pagination-container.hidden {
    display:none;
}
</style>

2. 滚动置顶的实现

上面的代码中引入了一个滚动置顶的方法,关于滚动置顶,虽然我们可以用scrollTo这个方法简单粗暴的实现,但是一个好的滚动方案需要考虑动画方案和滚动缓冲,以下是代码实现。

代码语言:javascript复制
// 速度递减算法
Math.easeInOutQuad = function (t, b, c, d) {
    t /= d / 2;
    if (t < 1) {
        return c / 2 * t * t   b;
    };
    t--;
    return -c / 2 * (t * (t - 2) - 1)   b;
};


// 采用的动画方案
var requestAnimFrame = (function () {
    return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60) }
})();


// 滚动页面所有
function move(amount) {
    document.documentElement.scrollTop = amount;
    document.body.parentNode.scrollTop = amount;
    document.body.scrollTop = amount;
}

// 页面滚动位置
function position() {
    return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop;
}


// 滚动执行方法
export function scrollTo(to, duration, callback) {
    const start = position();
    const change = to - start;
    const increment = 20;
    let currentTime = 0;
    duration = (typeof (duration) === 'undefined') ? 500 : duration;
    var animateScroll = function () {
        // 滚动时间递增
        currentTime  = increment;
        // 滚动距离递减
        var val = Math.easeInOutQuad(currentTime, start, change, duration);
        // 移动页面所有
        move(val);
        // 持续动画结束
        if (currentTime < duration) {
            requestAnimFrame(animateScroll);
        } else {
            if (callback && typeof (callback) === 'function') {
                // 执行完成后回调
                callback();
            }
        }
    };
    animateScroll();
}

3. 组件的使用示例

代码语言:javascript复制
<template>
    <div>
        <Pagination :total="total" @pagination="paginateChange"></Pagination>
    </div>
</template>

<script>

import Pagination from "@/components/Pagination";

export default {
    components:{
        Pagination:Pagination
    },
    data() {
        return {
            // 表格查询参数
            queryParams:{
                page:1,
                limit:20
            },
            // 表格数据汇总(后端接口查询返回赋值)
            total:100
        };
    },

    methods: {

        // 分页改变
        paginateChange(res){
            this.queryParams.page = res.page;
            this.queryParams.limit = res.limit;

            // 请求表格数据

        }
    }
};
</script>

0 人点赞