表单分页在后台管理系统中最为常见,几乎所有的表格页面都会用到,但是一般的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>