vue3封装自己的分页组件

下面是关于“vue3封装自己的分页组件”的完整攻略。

什么是分页组件

分页组件是前端常见的组件之一,用于展示大量数据时,将其拆分成多个页面展示,实现数据的分页浏览。包括页码、下一页、上一页、跳转页面等功能。

如何封装自己的分页组件

在 Vue3 中,可以使用 Composition API 封装自己的分页组件。下面是一个简易的分页组件封装示例:

  1. 引入 Pagination 组件
<template>
  <div>
    <ul class="pagination">
      <li :class="{disabled: currentPage == 1}" @click="prevPage"><a>上一页</a></li>
      <li v-for="page in totalPages" :key="page" :class="{active: currentPage === page}" @click="changePage(page)"><a>{{ page }}</a></li>
      <li :class="{disabled: currentPage == totalPages}" @click="nextPage"><a>下一页</a></li>
    </ul>
  </div>
</template>
  1. 创建 Pagination 组件

在创建 Pagination 组件时,需要考虑的是数据层的实现和方法的定义。下面给出一个简单的示例:

<script>
import { ref } from 'vue'

export default {
  props: {
    pageSize: {
      type: Number,
      default: 10 // 默认每页10条数据
    },
    total: {
      type: Number,
      default: 0 // 数据总数,默认为0
    }
  },
  setup(props, context) {
    const currentPage = ref(1) // 当前页码,默认为1
    const totalPages = ref(Math.ceil(props.total / props.pageSize)) // 总页数

    function changePage(page) {
      if (page > 0 && page <= totalPages.value) {
        currentPage.value = page
        context.emit('changePage', currentPage.value)
      }
    }

    function prevPage() {
      if (currentPage.value > 1) {
        currentPage.value--
        context.emit('changePage', currentPage.value)
      }
    }

    function nextPage() {
      if (currentPage.value < totalPages.value) {
        currentPage.value++
        context.emit('changePage', currentPage.value)
      }
    }

    return {
      currentPage,
      totalPages,
      changePage,
      prevPage,
      nextPage,
    }
  }
}
</script>

上面示例中,我们使用了 Composition API 中的 ref 用于数据的响应式处理。同时,定义了三个方法:changePage、prevPage 和 nextPage,用于响应页面切换的监听事件。

  1. 使用 Pagination 组件

在使用上述封装的 Pagination 组件时,我们需要传递两个参数:pageSize 和 total。pageSize表示每一页要显示的数据数量,total表示当前要展示的数据总数。同时可以监听组件emit出的changePage事件,来实现真正的数据展示更新。

<template>
  <div>
    <ul>
      <li v-for="item in displayedItems" :key="item">{{ item }}</li>
    </ul>
    <pagination :page-size="pageSize" :total="items.length" @changePage="handlePageChange" />
  </div>
</template>

<script>
import Pagination from './Pagination.vue'

export default {
  components: {
    Pagination
  },
  data() {
    return {
      currentPage: 1,
      pageSize: 10,
      items: [...], // 一大批数据
    }
  },
  computed: {
    displayedItems() {
      const start = (this.currentPage - 1) * this.pageSize
      const end = start + this.pageSize
      return this.items.slice(start, end)
    }
  },
  methods: {
    handlePageChange(page) {
      this.currentPage = page
    }
  }
}
</script>

上述示例中,handlePageChange 方法用于响应 Pagination 组件emit出的 changePage 事件,从而实现数据的更新。同时在 computed 中计算展示的数据列表,然后在模板中遍历展示即可。

示例

示例1:Vue3中使用分页组件

下面给出使用上述封装的 Pagination 组件的示例。在组件内部通过计算currentPage和displayedItems,将数据进行分页,并更新界面。

<template>
  <div>
    <ul>
      <li v-for="item in displayedItems" :key="item">{{ item }}</li>
    </ul>
    <pagination :page-size="pageSize" :total="items.length" @changePage="handlePageChange" />
  </div>
</template>

<script>
import Pagination from './Pagination.vue'

export default {
  components: {
    Pagination
  },
  data() {
    return {
      currentPage: 1,
      pageSize: 10,
      items: [1, 2, 3, ...,100], // 一大批数据
    }
  },
  computed: {
    displayedItems() {
      const start = (this.currentPage - 1) * this.pageSize
      const end = start + this.pageSize
      return this.items.slice(start, end)
    }
  },
  methods: {
    handlePageChange(page) {
      this.currentPage = page
    }
  }
}
</script>

示例2:增加一些自定义配置来实现更加灵活的功能

在上述示例中,Pagination 组件的上一页、下一页和数字页码部分均是写死的,无法进行自定义。下面对该组件进行升级,增加自定义配置功能。示例代码如下:

<template>
  <div>
    <ul class="pagination">
      <li :class="{['disabled', prevDisabled]}"><a @click.stop.prevent="prevPage">{{ prevButtonText }}</a></li>
      <li v-for="page in visiblePages" :key="page" :class="{active: currentPage === page}" @click.stop.prevent="changePage(page)"><a>{{ page }}</a></li>
      <li :class="{['disabled', nextDisabled]}"><a @click.stop.prevent="nextPage">{{ nextButtonText }}</a></li>
    </ul>
  </div>
</template>

<script>
import { ref, computed } from 'vue'

export default {
  props: {
    pageSize: {
      type: Number,
      default: 10 // 默认每页10条数据
    },
    total: {
      type: Number,
      default: 0 // 数据总数,默认为0
    },
    prevButtonText: {
      type: String,
      default: '上一页' // 上一页按钮的文本
    },
    nextButtonText: {
      type: String,
      default: '下一页' // 下一页按钮的文本
    },
    visiblePages: {
      type: Number,
      default: 5 // 可见页码数量(不包括上一页和下一页按钮)
    }
  },
  setup(props, context) {
    const currentPage = ref(1) // 当前页码,默认为1
    const totalPages = ref(Math.ceil(props.total / props.pageSize)) // 总页数

    function changePage(page) {
      if (page > 0 && page <= totalPages.value) {
        currentPage.value = page
        context.emit('changePage', currentPage.value)
      }
    }

    function prevPage() {
      if (currentPage.value > 1) {
        currentPage.value--
        context.emit('changePage', currentPage.value)
      }
    }

    function nextPage() {
      if (currentPage.value < totalPages.value) {
        currentPage.value++
        context.emit('changePage', currentPage.value)
      }
    }

    const prevDisabled = computed(() => currentPage.value === 1)
    const nextDisabled = computed(() => currentPage.value === totalPages.value)

    const visiblePagesCount = computed(() => {
      return totalPages.value > props.visiblePages ? props.visiblePages : totalPages.value
    })

    const centerIndex = computed(() => {
      return Math.floor(visiblePagesCount.value / 2) + (visiblePagesCount.value % 2)
    })

    const pageStart = computed(() => {
      const start = currentPage.value - centerIndex.value
      return start < 0 ? 0 : start
    })

    const visiblePages = computed(() => {
      const adjustedEnd = Math.min(totalPages.value, pageStart.value + visiblePagesCount.value)
      const arr = []
      for (let i = pageStart.value; i < adjustedEnd; i++) {
        arr.push(i + 1)
      }
      return arr
    })

    return {
      currentPage,
      totalPages,
      changePage,
      prevPage,
      nextPage,
      prevDisabled,
      nextDisabled,
      visiblePages
    }
  }
}
</script>

上述示例中,我们增加了三个可选的 props 属性:prevButtonText、nextButtonText 和 visiblePages,分别用于设置上一页和下一页按钮的文本以及可见页码数量。同时在 setup 中使用 computed 计算出当前可见页码,增加了更多的自定义和灵活性。

总结

本文详细讲解了“Vue3封装自己的分页组件”的完整攻略,分别从引入和创建组件、使用组件以及示例说明等方面进行了讲解。Vue3的Composition API让组件的实现变得更加灵活和简便,同时还对其进行了增强,创造出了更多的组件开发方式和模式。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue3封装自己的分页组件 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • Java数据结构之红黑树的原理及实现

    Java数据结构之红黑树的原理及实现 1. 红黑树的概述 红黑树是一种自平衡二叉查找树。在二叉查找树中,左节点的值比父节点的值小,右节点的值比父节点的值大,而红黑树中还有两个特殊的规则: 每个节点不是红色就是黑色 根节点是黑色的 这两个规则确保了红黑树的平衡性和搜索性能。 红黑树是通过颜色标记来区分每个节点,一般使用红色来表示,所以得名为红黑树。 2. 插入…

    other 2023年6月27日
    00
  • win7 32位和64位有什么区别哪一个好用率高一些

    Win7 32位和64位的区别及选择攻略 区别 架构差异:Win7 32位系统是基于x86架构,而64位系统是基于x64架构。64位系统支持更大的内存寻址空间,可以处理更多的数据,而32位系统则受限于4GB内存寻址上限。 性能差异:64位系统在处理大型应用程序和多任务时表现更出色,因为它可以同时处理更多的数据。而32位系统在处理较小的应用程序和简单任务时可能…

    other 2023年7月28日
    00
  • 右键显示(隐藏)扩展名的bat代码

    要让Windows系统上的文件扩展名显示或隐藏,可以使用一些批处理命令来完成。下面是一些可用的bat代码来实现这个功能。 显示文件扩展名的bat代码 要显示文件扩展名,请按照以下步骤进行操作: 新建一个文本文件并将其保存为showfileext.bat。 双击打开showfileext.bat,然后在文件中输入以下代码: @echo off reg add …

    other 2023年6月27日
    00
  • java通过AOP实现全局日志打印详解

    Java通过AOP实现全局日志打印详解 1. 简介 AOP(面向切面编程)是一种编程范式,可以通过在运行时动态地将代码片段(称为“切面”)插入到程序的特定位置,从而实现一些横切关注点的统一处理。全局日志打印是一个常见的横切关注点,可以通过AOP来实现。 2. 准备工作 在使用AOP实现全局日志打印之前,需要先引入相关的依赖库。这里以使用Spring框架为例,…

    other 2023年6月28日
    00
  • Android编程实现自定义手势的方法详解

    为了实现Android自定义手势,我们需要遵循以下步骤: 1. 声明手势识别器 在Android应用中声明一个GestureDetector实例。手势识别器负责识别手势事件并将其转换为对应的回调方法。 private GestureDetector mGestureDetector = new GestureDetector(context, new Ges…

    other 2023年6月25日
    00
  • Spring MVC学习教程之RequestMappingHandlerAdapter详解

    Spring MVC学习教程之RequestMappingHandlerAdapter详解 RequestMappingHandlerAdapter是Spring MVC框架中的一个关键组件,用于处理请求映射和方法调用之间的逻辑。在本教程中,我们将详细介绍RequestMappingHandlerAdapter的使用和配置。 1. 配置RequestMapp…

    other 2023年10月14日
    00
  • Springboot项目中单元测试时注入bean失败的解决方案

    Spring Boot项目中单元测试时注入Bean失败的解决方案 在Spring Boot项目中,有时在编写单元测试时可能会遇到注入Bean失败的情况。这可能是由于测试环境的配置不完整或依赖项未正确加载所致。以下是解决这个问题的完整攻略: 步骤1:检查测试类的注解配置 确保测试类上使用了@RunWith(SpringRunner.class)和@Spring…

    other 2023年10月13日
    00
  • Flutter开发之路由与导航的实现

    Flutter开发之路由与导航的实现攻略 在Flutter开发中,路由(Route)和导航(Navigation)是非常重要的概念。路由用于管理应用程序中不同页面的切换,而导航则是指导用户在应用程序中进行页面切换的过程。本攻略将详细介绍如何在Flutter中实现路由和导航。 1. 路由的基本概念 在Flutter中,每个页面都可以看作是一个路由。路由之间的切…

    other 2023年7月28日
    00
合作推广
合作推广
分享本页
返回顶部