Skip to content

usePagination

分页管理 hook,结合了 useRequest 和 Element Plus 的分页组件,提供完整的分页功能。

功能特性

  • 🔄 自动分页参数管理
  • 📊 支持全局分页配置
  • 🎯 与 Element Plus Pagination 组件完美集成
  • ⚡ 自动处理页码和每页大小变化

基本用法

vue
<template>
  <div>
    <!-- 使用 EplTable 组件,内置分页功能 -->
    <EplTable
      v-loading="loading"
      v-model="data"
      :columns="columns"
      :pageProps="pageProps"
      v-model:pageSize="pageSize"
      v-model:currentPage="currentPage"
    />
  </div>
</template>

<script setup>
import { computed } from 'vue';
import { EplTable, usePagination } from 'element-plus-lego';

// 模拟 API 请求
const fetchUsers = async params => {
  const response = await fetch('/api/users', {
    method: 'POST',
    body: JSON.stringify(params),
  });
  return response.json();
};

// 使用分页 hook
const { pageProps, loading, params, pageSize, currentPage, data, run } =
  usePagination(fetchUsers, {
    pagination: {
      totalKey: 'total',
      pageSizeKey: 'pageSize',
      currentPageKey: 'currentPage',
      pageSize: 10,
    },
  });

// 表格列配置
const columns = computed(() => [
  {
    prop: 'name',
    label: '姓名',
    width: '180',
    compType: 'input',
  },
  {
    prop: 'age',
    label: '年龄',
    compType: 'input',
    compProps: {
      type: 'number',
    },
  },
  {
    prop: 'email',
    label: '邮箱',
    compType: 'input',
  },
  {
    prop: 'status',
    label: '状态',
    compType: 'select',
    compProps: {
      options: [
        { label: '启用', value: 'active' },
        { label: '禁用', value: 'inactive' },
      ],
    },
  },
]);
</script>

高级用法

vue
<template>
  <div>
    <!-- 搜索表单 -->
    <EplSearch
      v-model="searchParams"
      :items="searchItems"
      :emits="searchEmits"
    />

    <!-- 数据表格 -->
    <EplTable
      v-loading="loading"
      v-model="data"
      :columns="columns"
      :pageProps="pageProps"
      v-model:pageSize="pageSize"
      v-model:currentPage="currentPage"
      border
    >
      <template #actions="{ row }">
        <el-button type="primary" link @click="handleEdit(row)">编辑</el-button>
        <el-button type="danger" link @click="handleDelete(row)">
          删除
        </el-button>
      </template>
    </EplTable>
  </div>
</template>

<script setup>
import { computed, ref } from 'vue';
import { EplTable, EplSearch, usePagination } from 'element-plus-lego';

// 搜索参数
const searchParams = ref({
  name: '',
  status: '',
  department: 'IT',
});

// 搜索表单项配置
const searchItems = computed(() => [
  {
    label: '姓名',
    prop: 'name',
    compType: 'input',
    compProps: {
      placeholder: '请输入姓名',
    },
  },
  {
    label: '状态',
    prop: 'status',
    compType: 'select',
    compProps: {
      placeholder: '请选择状态',
      options: [
        { label: '启用', value: 'active' },
        { label: '禁用', value: 'inactive' },
      ],
    },
  },
]);

// 搜索按钮配置
const searchEmits = [
  {
    type: 'primary',
    name: '搜索',
    nativeType: 'submit',
    onClick: handleSearch,
  },
  {
    name: '重置',
    onClick: handleReset,
  },
];

// 自定义分页配置
const { pageProps, loading, params, pageSize, currentPage, data, run } =
  usePagination(fetchUsers, {
    // 初始参数
    params: searchParams,

    // 分页配置
    pagination: {
      totalKey: 'totalCount', // 后端返回的总数字段
      pageSizeKey: 'size', // 后端接收的每页大小字段
      currentPageKey: 'pageNum', // 后端接收的页码字段
      pageSize: 20, // 默认每页条数

      // Element Plus Pagination 的其他属性
      background: true,
      hideOnSinglePage: false,
      layout: 'total, sizes, prev, pager, next, jumper',
    },

    // useRequest 的其他选项
    immediate: true,
    delay: 300,
  });

// 表格列配置
const columns = computed(() => [
  {
    prop: 'name',
    label: '姓名',
    width: '180',
    compType: 'input',
  },
  {
    prop: 'age',
    label: '年龄',
    compType: 'input',
    compProps: {
      type: 'number',
    },
  },
  {
    prop: 'email',
    label: '邮箱',
    compType: 'input',
  },
  {
    prop: 'status',
    label: '状态',
    compType: 'select',
    compProps: {
      options: [
        { label: '启用', value: 'active' },
        { label: '禁用', value: 'inactive' },
      ],
    },
  },
  {
    label: '操作',
    prop: 'actions',
    width: '140',
  },
]);

// API 请求函数
async function fetchUsers(params) {
  const response = await fetch('/api/users', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(params),
  });
  return response.json();
}

// 搜索
const handleSearch = () => {
  currentPage.value = 1;
  run();
};

// 重置
const handleReset = () => {
  searchParams.value = {
    name: '',
    status: '',
    department: 'IT',
  };
  currentPage.value = 1;
  run();
};

// 编辑
const handleEdit = row => {
  console.log('编辑', row);
};

// 删除
const handleDelete = row => {
  console.log('删除', row);
};
</script>

API 参数

参数类型默认值说明
serviceTService-请求服务函数
options.pagination.totalKeystring'total'后端返回数据中总条数的字段名
options.pagination.pageSizeKeystring'pageSize'后端返回数据中每页大小的字段名
options.pagination.currentPageKeystring'currentPage'后端返回数据中当前页码的字段名
options.pagination.pageSizenumber10默认每页显示的条数
options.paramsany{}额外的请求参数
options.immediatebooleantrue是否立即执行请求
options.delaynumber0防抖延迟时间(毫秒)

返回值

属性类型说明
pagePropsRef<TPageProps>Element Plus Pagination 组件的属性
loadingRef<boolean>加载状态
paramsRef<any>请求参数(包含分页参数)
pageSizeRef<number>每页大小
currentPageRef<number>当前页码
dataRef<any>响应数据
run() => void手动执行请求

全局配置

通过插件注册时的 pagination 选项可以设置全局分页配置:

ts
// main.ts
import ElementPlusLego from 'element-plus-lego';

const pagination = {
  totalKey: 'totalCount',
  pageSizeKey: 'size',
  currentPageKey: 'pageNum',
  pageSize: 20,
};

app.use(ElementPlusLego, { pagination });

全局配置会被所有 usePagination 实例继承(后续所有分页请求只需传入剩余参数即可),但可以在具体使用时覆盖。