自定义Pagination组件

自定义Pagination分页组件

最近在学Vue.js框架,理论知识学得再多,不如自己实践一遍,获得更深的感悟。因此决定封装Element-UI 的Pagination分页组件

以下代码中的特性使用的是Vue2版本

el-pagination

从官网拷贝代码如下:

<template>
    <div class="block">
        <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-sizes="[100, 200, 300, 400]"
        :page-size="100"
        layout="total, sizes, prev, pager, next, jumper"
        :total="400">
        </el-pagination>
    </div>
</templete>

<script>
  export default {
    methods: {
      handleSizeChange(val) {
        console.log(`每页 ${val}`);
      },
      handleCurrentChange(val) {
        console.log(`当前页: ${val}`);
      }
    },
    data() {
      return {
        currentPage: 1
      };
    }
  }
</script>

size-change: 设置每页的数量,触发handleSizeChange 事件
current-change: 设置第几页,触发handleCurrentChange 事件
其他的字段就不在解释了,比较简单

在不封装的情况下,直接在组件内部使用此代码,修改比较简单:

  • page-sizes,page-size,total,currentPage 使用变量而非固定值
  • 事件触发时,修改配置,并重新获取表单中的数据来更新表单

封装分页组件

多个页面存在表单的情况,需要复制分页的代码和逻辑,比较麻烦!把具备通用性的分页组件封装起来会更加高效。

创建子组件

创建文件src/components/Pagination/index.vue

<template>
    <div  class="pagination-container">
        <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="pageNum"
        :page-sizes="pageSizes"    
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        >
        </el-pagination>
    </div>
</template>

<script>
export default {
    name: "MyPagination",
    props: { // 申明哪些参数,需要父组件传入进来,同时描述类型和默认值
        total: {
            require: true,
            type: Number
        },
        pageNum: {
            type: Number,
            default: 1
        },
        pageSize: {
            type: Number,
            default: 20
        },
        pageSizes: {
            type: Array,
            default() {
                return [10, 20, 30, 50]
            }
        },
    },
    data() {
        return { // 注意:此处没有设置任何数值
        }
    },
    methods: {
        handleSizeChange(val) {
            this.$emit('update:pageSize', val)   // 此处用来同步`pageSize`给父组件,注意`update:`前缀是固定写法
            // `pagination`是一个自定义事件,只要父组件和子组件默契的承接即可。父组件接受到此事件则刷新表单,pagination({pageNum:xxx, pageSize: xxx})
            this.$emit("pagination", {pageNum: this.pageNum, pageSize: this.pageSize}) 

        handleCurrentChange(val) {
            this.$emit("update:pageNum", val)  // 此处用来同步`pageNum`给父组件,注意`update:`前缀是固定写法
            this.$emit("pagination", {pageNum: this.pageNum, pageSize: this.pageSize})
        }
    }
}
</script>

分页组件中,只有pageNumpageSize 是用户经常设置,其他变量不变,可由父组件传入。
增加一个自定义pagination事件的原因,在于父组件能够根据事件,刷新表单数据,非常重要! 比通过监听变量的方式触发表单更新更加高效。

父组件代码如下:

<template>
<MyPagination :total="total" :pageNum.sync="queryParams.pageNum" :pageSize.sync="queryParams.pageSize" @pagination="getList"/>
</template>

<script>
export default {
    data(){
        return {
            tableData: [],
            queryParams: {
                pageNum: 1,
                pageSize: 10,
                num: null
           },
           total: 20,

        }
    },
    methods: {
        getList(data){
            console.log("更新表单数据")
        }
    }

}
<script>

:pageNum.sync 其中:pageNum是子组件中注册的pageNum, 同理:pageSize.sync是子组件注册的pageSize
@pagination 这个事件是必须与子组件中$emit("pagination")申明的事件保持一致

由于分页数据是常用的组件,则在全局注册

// main.js
import Vue from 'vue'
import Pagination from "@/components/Pagination"

Vue.component('MyPagination', Pagination)

new Vue({
    router,
    store,
    render: h => h(App)
}).$mount('#app')

知识点

父子组件的通信

父组件在模版中使用子组件,采用:pageSize:sync=pageSize,:pageSize.sync 表示在子组件中使用一个pageSize的属性值,由父组件中数据pageSize设置初始值
子组件通过props:{ pageSize: {type: Number}}中声明属性,可以通过this.pageSize进行访问,但是此属性不能直接赋值,但是可以使用this.$emit("update:pageSize", 2)进行传值。
当然更优雅的方式是给属性使用computed计算属性来定义一个新变量,此方法不在详细叙述。

自定义事件

子组件发送pagination事件this.$emit('pagination', data)给父组件
父组件定义了接收方法@pagination="getList"

总结

组件的封装的套路大体上是一致的,应该还涉及到一些知识点,比如v-model等,多做小项目,会加深理解,加油!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值