分页组件的二次封装
今天想来整理下毕设遇到的分页组件的封装问题,当时在做毕设的时候。原本没有想要去自己在封装下,但是到后面发现我多个页面都需要使用到分页,如果我自己不去封装的话,后面的工作量会非常的大,所以就自行的去撸代码了。
★这个是基于vue和element-ui做的项目,也是我第一次学完vue后,并且真正尝试去做的项目
”
- 将el-pagination封装在自己定义的组件中pagination.vue
<template>
<div class="block" v-if="bgDate.length !=0 ">
<el-pagination
//选择每页显示多少条数据方法
@size-change="handleSizeChange"
//当前页数方法
@current-change="handleCurrentChange"
// 当前页数
:current-page="currentPage"
//当前每页显示多少条数据
:page-sizes="pagesizes"
//默认每页条数
:page-size="sizeChange"
layout="total, sizes, prev, pager, next, jumper"
// 数据量
:total="dateSource.length"
//数据源
:date="dateSource"
></el-pagination>
</div>
</template>
- 分页组件所需要的一些数据
/**
* pagesizes==>[2, 3, 4, 5, 6]
* dateSource ==> 数据源(父组件传递的后台数据)
*/
//这两个变量是有父组件传过来的
props: ["pagesizes", "dateSource"],
data() {
return {
tableData: [], //存取组件渲染的数据
bgDate: [], //存取数据源
//默认每页条数
sizeChange: 5,
// 当前页数,支持 .sync 修饰符
currentPage: 1
};
}
- 父组件请求数据,并将数据传给子组件
// 获取所有小说
getAllStory() {
this.$axios.get("api2/users/getAllStroy").then(res => {
var storyDatas = res.data.data.storyDatas;
console.log("获取到所有小说数据",storyDatas);
//bgDate传递给分页组件的数据
this.bgDate = storyDatas;
});
},
但是问题来了,在父组件中使用axios获取异步数据传给子组件,但是发现子组件在渲染的时候并没有数据,在created里面打印也是空的,结果发现一开始子组件绑定的数据是空的,在请求数据没有返回数据时,子组件就已经加载了,并且他绑定的值也是空的,问题找到了,怎么解决那?有两种方法解决
第一种:
- 使用watch的方式监听数据源(父组件传来的数据)
watch: {
// 监听数据源dateSource,dateSource将会用到el-pagination中的:data上
dateSource(val) {
console.log("监听数据源:", val);
this.bgDate = val;
this.showPagination(this.currentPage);
}
},
- 第二种是使用到vuex,在这里我变不再赘述了,你们可以看下这篇文章
vue父组件异步获取动态数据传递给子组件 获取不到值的问题已完美解决
★组件加载渲染过程:父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted
”
数据源解决了,那接下来便是展示后台给的数据
//这个方法主要是用来判断当前页面显示什么数据
//通过当前页面数curPage,来判断从数据源中获取指定的数据
showPagination(curPage) {
console.log('页面数范围',curPage)
this.tableData = [];
var bgLen = this.bgDate.length;
//sizeChange 默认每页条数
var left = this.sizeChange * (curPage - 1);
var right = this.sizeChange * curPage;
for (var i = 0; i < bgLen; i++) {
if (i >= left && i < right) {
this.tableData.push(this.bgDate[i]);
}
}
// 触发父组件的方法(告知父组件显示什么数据)
this.$emit("showDate", this.tableData);
},
- 父组件
// 显示界面数据(点击分页按钮)
//接收子组件传来的数据
showDate(response) {
console.log('接收子组件传来的数据',response)
this.tableData = response;
},
最后遇到一个问题是,我在删除数据的时候,发现在最后一页删除最后一条数据分页完后,并不会自动跳到前一页面,而是停在当前页面。我自己写了一个方法解决这个问题。
// 删除item项
handleDelete() {
// /**
// * 作用:从后面开始删除数
// * 判断页面的数据是否没有,如果没有就自动跳转到前一页
// **/
this.showPagination(this.currentPage);
if (
Math.ceil(this.tableData.length / this.sizeChange) !=
this.currentPage &&
this.currentPage != 1
) {
this.handleCurrentChange(this.currentPage - 1);
}
}
然后通过父组件调用该方法
- 这个删除的方法
open(index, row) {
this.$confirm("此操作将永久删除此数据, 是否继续?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
this.$axios
.post("api2/users/deleteStory", { _id: row._id })
.then(res => {
var status = res.data.data.status;
if (status == 0) {
this.$message({
type: "success",
message: "删除小说成功!"
});
this.getAllStory();
// 通过this.$refs.mychild来调用子组件的跳转方法
this.$refs.mychild.handleDelete();
} else {
this.$message({
type: "waring",
message: "删除小说失败!"
});
}
});
})
.catch(() => {
this.$message({
type: "info",
message: "已取消删除"
});
});
},
以上是分页组件的封装内容,最后我们可以再任意一个需要分页的组件进行愉快的调用
import pagination from "@/components/pagination";
export default {
components: {
pagination
},
}
<!-- 分页 -->
<pagination ref="mychild" :pagesizes="[2,3,4,5,6]" :dateSource="bgDate" @showDate="showDate" />
最后展示下分页组件所在的页面
下面这三个仓库便是我的毕业设计项目
本文使用 mdnice 排版