el-pagination组件封装

组件使用

在这里插入图片描述
源代码:

<script setup>
import Pagination from '@/components/pagination/index.vue'
import {ref} from "vue";

const pageNum = ref(1)
const pageSize = ref(10)
const total = ref(120)

function loadData() {
  // 加载数据
}
</script>

<template>
  <Pagination v-model:page-num="pageNum"
              v-model:page-size="pageSize"
              :total="total"
              @loadData="loadData"
  />
</template>

<style lang="scss" scoped>
</style>

组件属性

名称类型默认值是否必需说明
pageNumNumber1v-model:pageNum双向绑定属性,
pageSizeNumber10v-model:pageSize双向绑定属性
pagerCountNumber5需要显示的页码号数量
pageSizesArray[5,10,15,20]每页的大小
layoutString‘’prev, pager, next, jumper,total,sizes布局
totalNumber0总条数

组件事件

名称参数列表说明
loadData加载分页数据

第三方

// npm install @vueuse/core@11.1.0
import {useDebounceFn} from "@vueuse/core";

外部常量

export const Constants = {
    // xs 屏幕宽度(单位:px)
    XS_WIDTH: 768,
}

外部函数

// 获取浏览器窗口宽度
export function getClientWidth(){
    return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth
}

组件源码:

<script setup>
import {computed, onMounted, ref, watch} from "vue";
import {getClientWidth} from "@/util/system.js";
import {Constants} from "@/setting.js";
import {useDebounceFn} from "@vueuse/core";

const emit = defineEmits(['loadData', 'update:pageNum', 'update:pageSize'])
const prop = defineProps({
  pageNum: {
    type: Number,
    default: 1
  },
  pageSize: {
    type: Number,
    default: 10
  },
  pagerCount: {
    type: Number,
    default: 5
  },
  pageSizes: {
    type: Array,
    default: [5, 10, 15, 20]
  },
  layout: {
    type: String,
    default: ''
  },
  total: {
    type: Number,
    default: 0
  }
})

// 窗口宽度
const clientWidth = ref(getClientWidth())

// 窗口大小改变回调
function handleClientWidth() {
  clientWidth.value = getClientWidth()
}

const pageNum1 = ref(prop.pageNum)
const pageSize1 = ref(prop.pageSize)
const pagerCount1 = computed(() => prop.pagerCount)
const pageSizes1 = computed(() => prop.pageSizes)
const layout1 = computed(() => {
  if (!prop.layout) {
    // 可视宽度是否小于768px
    return clientWidth.value < Constants.XS_WIDTH ? 'prev, pager, next, total' : 'prev, pager, next, jumper,total,sizes'
  } else {
    return prop.layout
  }
})
const total1 = computed(() => prop.total)

// 监听pageNum和pageSize的变化
watch([pageNum1, pageSize1], ([newPageNum, newPageSize]) => {
  emit('update:pageNum', newPageNum)
  emit('update:pageSize', newPageSize)
  // 节流函数,加载新数据
  loadData()
})

// 防抖函数,处理页大小改变导致页号改变,连续发送两次请求的情况
const loadData = useDebounceFn(() => {
  emit('loadData')
}, 800)

onMounted(() => {
  window.addEventListener("resize", handleClientWidth)
})
</script>
<template>
  <el-pagination
      v-model:current-page="pageNum1"
      v-model:page-size="pageSize1"
      :page-sizes="pageSizes1"
      :layout="layout1"
      :pager-count="pagerCount1"
      :total="total1"
      hide-on-single-page
  />
</template>

<style lang="scss" scoped>

</style>

### 封装 `el-pagination` 组件 为了在 Vue 3 中使用 Setup 语法糖来封装 Element Plus 的 `el-pagination` 组件,可以创建一个新的组合式 API 函数以便于重用逻辑。下面是一个具体的实现例子。 #### 创建自定义 Hook 首先,在项目中新建一个文件夹用于存放可复用的钩子函数,比如命名为 `composables` 文件夹,并在此目录下建立名为 `usePagination.js` 或者 `.ts` 的文件: ```javascript // composables/usePagination.ts import { ref, computed } from 'vue' export function usePagination(totalPages = 10) { const currentPage = ref(1) const handleCurrentChange = (val) => { currentPage.value = val } return { currentPage, totalPages: computed(() => totalPages), handleCurrentChange } } ``` 此部分代码通过组合式API提供了分页所需的基础属性和方法[^1]。 #### 使用自定义Hook构建组件 接着可以在单文件组件(SFC)里引入并应用这个 hook 来简化模板中的逻辑处理: ```html <template> <div class="pagination-container"> <!-- 这里的 :total 和 @current-change 是 el-pagination 需要绑定的数据 --> <el-pagination background layout="prev, pager, next" :total="props.total * 10" :page-size="10" v-model:currentPage="state.currentPage" @current-change="handlePageChange"/> </div> </template> <script setup lang="ts"> import { defineProps, reactive } from 'vue' import { usePagination } from '../composables/usePagination' const props = defineProps({ total: Number // 总条目数 }) let state = reactive(usePagination(props.total)) function handlePageChange(val){ console.log(`当前页: ${val}`) } </script> <style scoped> .pagination-container{ margin-top: 20px; text-align:center; } </style> ``` 上述代码展示了如何利用 `<script setup>` 结合 TypeScript 定义了一个响应式的 pagination 组件实例[state], 并将其与 template 中的 `v-model` 及事件监听器关联起来.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值