vue element-ui之分页组件的封装

目录

为什么要封装分页组件?

分页组件的封装

如何使用?

为什么要封装分页组件?

分页组件用的最多的就是和表格一起,构成表格数据的翻页显示,当然也不仅限于表格,例如其它的流式加载、图片分批次加载等,都会用到分页组件。

这里以表格为例,通常我们写一个分页展示的表格,都会写一个<el-table></el-table>,然后在下面再写一个<el-pagination></el-pagination>的分页组件,分页组件里面有很多参数和触发函数,比如::page-sizes :total :current-page :page-size 及 layout等,触发函数一般有 @current-change @size-change 等,而以上的参数和触发函数对于一个项目中用到的所有分页组件几乎都是一样的,如果我们每写一个翻页表格,再写一个分页组件,这样就会显得很啰嗦,重复代码多。

这里,我们把<el-pagination>组件进一步封装成<XxPagination>,引入前端工程中,再写翻页表格时,只需引入<XxPagination>或有按需求传入自己的参数,不需要写重复的参数和触发函数。

分页组件的封装

这个分页组件是我同事封装的,简单、易用。用到了 Vue.js 2.2.0 版本后新增的 API provide/inject,来进行父子组件之间的参数传递。它的特性是在父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量。这种方式可以避免在使用props传值时,必须将每一个属性都传递给子组件的写法,当使用的公共组件不确定会被传递什么值的时候,使用这种写法非常方便。

此外,我们还用到了vue中的mixinsmixins就是定义一部分公共的方法或者计算属性,然后混入到各个组件中使用,方便管理与统一修改。若有不理解的可以百度了解一下哦。

首先,按照上一篇vue element-ui之怎么封装一个自己的组件中的方法,我们在components下创建一个xx-pagination文件夹,然后在下面创建一个index.vue,代码如下:

<template>
  <el-pagination
    @current-change="onPageChange"
    @size-change="onPageSizeChange"
    :page-sizes="[10, 20, 50, 100]"
    :total="iTotal"
    :current-page="iCurrentPage"
    :page-size="iPageSize"
    layout="total, sizes, prev, pager, next, jumper"
  ></el-pagination>
</template>
<script>
export default {
  name: 'XxPagination', // 组件名
  inject: ['pagination'], // 接收后面mixins中provider的提供的参数
  props: {
    total: { // 总页数
      type: Number,
      default: 0
    },
    currentPage: { // 当前页
      type: Number,
      default: 1
    },
    pageSize: { // 每页显示条数
      type: Number,
      default: 10 // 默认10条
    }
  },
  watch: {
    pagination: { // 监听器
      deep: true,
      handler(v) {
        if (!v) {
          return
        }
        const { pageSize, total, currentPage } = v
        this.iPageSize = pageSize
        this.iTotal = total
        this.iCurrentPage = currentPage
      }
    }
  },
  data() {
    return {
      iPageSize: this.pageSize,
      iCurrentPage: this.currentPage,
      iTotal: this.total
    }
  },
  methods: {
    _emitPaginationChangeInfo() { // 触发父组件中特定的pageChanged函数
      const pageInfo = {
        pageSize: this.iPageSize,
        currentPage: this.iCurrentPage
      }
      this.$emit('pageChanged', pageInfo)
    },
    onPageSizeChange(pageSize) { // 每页条数改变函数
      const willMakePageChange = this.total / pageSize + 1 < this.iCurrentPage
      this.iPageSize = pageSize
      // 可能会造成页码改变发生,这时候不发送事件,因为可能造成事件死循环
      if (!willMakePageChange) {
        this._emitPaginationChangeInfo()
      }
    },
    onPageChange(currentPage) { // 页码改变函数
      this.iCurrentPage = currentPage
      this._emitPaginationChangeInfo()
    }
  }
}
</script>

inject: ['pagination']   接收mixins的provider提供的参数值。

props: total总数, currentPage当前页码,pageSize每页显示条数。

watch:监听'pagination' 参数的改变,pagination是个对象,包含pageSize, total, currentPage

methods:_emitPaginationChangeInfo()函数会触发父组件中的pageChanged()函数,因此在使用XxPagination的父组件中要求自定义一个pageChanged()函数并自己实现触发后的相关逻辑。onPageSizeChange(pageSize)页面显示条数改变触发函数。onPageChange(currentPage)页码改变触发函数。

好了,接下来就是我们的mixins。在项目中创建一个js文件,我这里命名为PageMixins.js,具体代码如下:

import _ from 'lodash'

export default {
  provide() { // 这里定义provide 传递参数
    return {
      data: this.data || {}, // 表格数据
      pagination: this.pagination // 分页属性
    }
  },
  data() {
    return {
      data: [],
      pagination: {
        currentPage: 1,
        total: 0,
        pageSize: 10
      }
    }
  },
  methods: {
    onGotPageData({ content, totalElements, size, number }) {
      this.data = content
      this.pagination.currentPage = number + 1
      this.pagination.pageSize = size
      this.pagination.total = totalElements
    },
    onPageChanged({ currentPage, pageSize }) {
      this.pagination.currentPage = currentPage
      this.pagination.pageSize = pageSize
      if (this.getData) {
        this.getData()
      }
    },
    addPageInfo(params = {}) {
      Object.assign(params, {
        pageSize: this.pagination.pageSize,
        pageNumber: this.pagination.currentPage - 1
      })
      return params
    }
  }
}

provide:这里定义的就是上面inject接收的参数。

methods:addPageInfo()函数,把请求后台的参数传递进来,然后加上分页参数,包装成一个对象返回;onGotPageData()函数,在页面返回数据后调用,给分页组件设置后台返回的值。onPageChanged()函数,页码改变触发,然后调用父组件的getData()函数。

如何使用?

<template>
  <!-- 就这么写一下可以了,这里会自动绑定分页数据以及触发数据请求 -->
  <XxPagination @pageChanged="onPageChanged"></XxPagination>
</template>

<script>
import PageMixins from '@/pages/common/mixins/PageMixins'

export default {
  mixins: [PageMixins],
  methods: {
    // 页面改变时,会主动掉头getData,因此必须定义getData函数,
    async getData() {
      // 为params上加入分页参数
      const params={}
      const data = await getAll(this.addPageInfo(params))
      // 处理分页数据
      this.onGotPageData(data)
    }
  },
}
</script>

上面讲解的可能不太明白,额,估计也很难说明白,但细心的你仔细读一下代码就能理解了。后续我会把这些组件的一些例子上传到github,等我有空吧哈哈哈。

  • 8
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
Vue2中,对于element-ui组件的二次封装,可以按照以下步骤进行: 1. 需求分析:明确需要封装element-ui组件,以及需要添加的功能和配置项。 2. 创建父组件:编写父组件的template和script代码,其中template中调用封装组件,script中定义需要传递给封装组件的props属性。 3. 创建封装组件:编写封装组件的template和script代码。在template中使用element-ui组件,并根据需要进行样式和布局的调整。在script中定义props属性,接收父组件传递的值,并监听element-ui组件的事件,触发update事件给父组件。 4. 通过临时变量传递值:由于父组件传递给封装组件的props不能直接作为封装组件的v-model属性传递给element-ui组件,所以需要在封装组件中定义一个临时变量来存储值,并将该变量与element-ui组件进行绑定。 5. 完成打通:在封装组件中监听中间件,接收到element-ui组件的update事件后,再将该事件传递给父组件。 总结来说,Vue2中对于element-ui组件的二次封装,需要创建父组件封装组件,通过props属性传递值,并在封装组件中监听element-ui组件的事件并触发update事件给父组件。同时,需要使用临时变量来传递值给element-ui组件。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Vue3+ts+element-plus 组件的二次封装-- 页脚分页el-pagination的二次封装](https://blog.csdn.net/cs492934056/article/details/128096257)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值