Vue 3 中分页器组件的封装升级

在 Vue 3 中,随着 Composition API 的引入,组件的封装和复用变得更加灵活和强大。同时本人也是注意到前一个组件在使用时存在的诸多小问题,本文将介绍如何将组件升级同时使用到到 Vue 3新版本的全新内容,并利用 Vue 3 的 Composition API 进行重构,使其更加符合现代 Vue 应用的开发模式。

原始组件回顾

原始的分页器组件使用了 ref 和 defineEmits 来管理状态和事件。主要通过覆盖ref变量来完成逻辑,但是这样后期开发会遇到很多隐患

<template>
  <!-- 分页 -->
  <el-pagination class="custom_page" :currentPage="currentPage" :page-size="pageSize"
    :page-sizes="pageSizes" :disabled="disabled" :background="background" :total="total" :pager-count="pagerCount"
    @size-change="handleSizeChange" @current-change="handleCurrentChange" />
</template>
 
<script setup>
 
import { ref, defineEmits } from 'vue';
const currentPage = ref(3);
const pageSize = ref(10);
const pageSizes = [10, 20, 30, 40];
const background = ref(true);
const disabled = ref(false);
const total = ref(100)
const pagerCount = ref(7)
const emit = defineEmits(['update:currentPage', 'update:pageSize']);
 
const handleSizeChange = (val) => {
  console.log(`${val} items per page`)
  emit('update:pageSize', val);
}
const handleCurrentChange = (val) => {
  console.log(`current page: ${val}`)
  emit('update:currentPage', val)
}
</script>
<style>
//这里可以添加子组件的其他样式....
</style>

 Vue 3 升级后的组件

新版本采用了defineModel()进行双向绑定,对于不需要双向绑定的变量采用defineProps()只允许父传子值,并在父级调用的时候将数据传入子组件。

这里直接奉上改良后的子组件代码:
<template>
  <!-- 分页 -->
  <el-pagination class="custom_page" :currentPage="currentPage" :page-size="pageSize" :page-sizes="props.pageSizes"
    :background="props.background" :total="props.total" :pager-count="props.pagerCount" @size-change="handleSizeChange"
    @current-change="handleCurrentChange" />
</template>

<script setup>
const currentPage = defineModel("currentPage", { type: Number, default: 4 })
const pageSize = defineModel("pageSize", { type: Number, default: 10 })

const emits = defineEmits(["handleSizeChange", "handleCurrentChange"])
const props = defineProps({
  total: {
    type: Number,
    default: 0
  },
  background: {
    type: Boolean,
    default: true
  },
  pageSizes: {
    type: Array,
    default: [10, 20, 30, 40]
  },
  pagerCount: {
    type: Number,
    default: 9
  },
})
function handleSizeChange(val) {
  // 在被修改时,触发 "update:count" 事件
  console.log(`${val} items per page`)
  pageSize.value = val
  emits('handleSizeChange', val);
}
function handleCurrentChange(val) {
  currentPage.value = val
  console.log(`current page: ${val}`)
  emits('handleCurrentChange', val);
}

</script>

<style lang="less" scoped>
//这里可以自定义样式
</style>
  • 使用<el-pagination>组件来展示分页控件。这个组件是Element Plus库提供的,用于实现分页功能。
  • :currentPage:page-size:page-sizes:background:total:pager-count是传递给<el-pagination>组件的props,分别控制当前页码、每页显示条目个数、可选择的每页显示个数、背景色、总条目数、分页器大小内按钮的个数。
  • @size-change@current-change是监听分页器页大小变化和当前页变化的事件,分别绑定了handleSizeChangehandleCurrentChange方法。
  • 属性(Props):定义了传递给组件的props,包括total(总条目数)、background(是否显示背景色)、pageSizes(每页显示条目的选择数组)、pagerCount(分页器大小内按钮的个数)。
  • 事件(Emits):定义了组件可以触发的自定义事件,这里是handleSizeChangehandleCurrentChange,用于在页大小或当前页变化时通知父组件。
  • 方法
    : - handleSizeChange:当页大小变化时调用,更新pageSize``的值并触发handleSizeChange`事件。
    • handleCurrentChange:当当前页变化时调用,更新currentPage的值并触发handleCurrentChange`事件。
父组件引用如下:
<template>

<!-- 父组件引用 -->
        <Paginations :total="total" :currentPage="currentPage" :pageSize="pageSize"
          layout=" prev, pager, next,sizes,jumper"  @handleSizeChange="handleSizeChange"
          @handleCurrentChange="handleCurrentChange" />

</template>

<script setup>

import { ref } from 'vue';
import Paginations from '@web/views/components/paginations.vue';

const currentPage = ref(8)
const total = ref(1000)
const pageSize = ref(11)

const handleSizeChange = (ref) => {
  console.log(ref, '父组调用Size方法')
  pageSize.value = ref
}
const handleCurrentChange = (ref) => {
  console.log(ref, '父组件调用Current方法')
  currentPage.value = ref
}

</script>
  1. Props 的使用:通过 defineProps 接收外部传入的属性,如 totalbackgroundpageSizes 和 pagerCount

  2. 内部状态管理:使用 ref 来管理内部状态,如 currentPage 和 pageSize

  3. 模板绑定:在模板中,通过 v-bind 或简写 : 将 props 和内部状态绑定到 el-pagination 组件上。

  4. 样式作用域:在 <style> 标签中使用 scoped 属性,确保样式只应用于当前组件。

  5. 导入和注册组件:导入了自定义的分页组件Paginations,并在模板中进行了引用。

  6. 响应式数据:使用ref函数创建了三个响应式数据totalcurrentPagepageSize,分别用于存储总条目数、当前页码和每页显示的条目数。

  7. 方法定义

    • handleSizeChange:处理页大小变化的事件。当分页组件的页大小发生变化时,会触发这个事件,并将新的页大小作为参数传递给这个方法。方法内部更新了pageSize的值,并打印了相关信息。
    • handleCurrentChange:处理当前页变化的事件。当分页组件的当前页发生变化时,会触发这个事件,并将新的当前页码作为参数传递给这个方法。方法内部更新了currentPage的值,并打印了相关信息。

总结 

以上就是所有代码,在前文的基础上进行了更新,用到了最新的方法。这里直接复制粘贴即可。

  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值