element-ui的分页组件二次封装

2,015 阅读2分钟

分页组件的二次封装

今天想来整理下毕设遇到的分页组件的封装问题,当时在做毕设的时候。原本没有想要去自己在封装下,但是到后面发现我多个页面都需要使用到分页,如果我自己不去封装的话,后面的工作量会非常的大,所以就自行的去撸代码了。

这个是基于vueelement-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" />

最后展示下分页组件所在的页面

下面这三个仓库便是我的毕业设计项目

基于vue的--Agoni小说网站

基于vue和element-ui的小说网站后台

基于node和mongoDB开发的后台接口

本文使用 mdnice 排版