Skip to content

Pagination 分页

分页组件,用于数据的分页展示。

基础用法

html
<div id="demo-pagination"></div>

<script>
  const pagination = new SaPagination('#demo-pagination', {
    total: 100,
    pageSize: 10,
    current: 1,
    onChange: (page, pageSize) => {
      console.log('当前页:', page, '每页条数:', pageSize);
    }
  });
</script>
加载 SanoUI 组件中...
            
          

完整布局

显示所有分页元素:总数、上一页、页码、下一页、跳转等。

html
<div id="demo-pagination-full"></div>

<script>
  const pagination = new SaPagination('#demo-pagination-full', {
    total: 100,
    pageSize: 10,
    current: 1,
    layout: 'total, prev, pager, next, jumper',
    onChange: (page, pageSize) => {
      console.log('页码变化:', page, pageSize);
    }
  });
</script>
加载 SanoUI 组件中...
            
          

简单布局

只显示上一页、下一页按钮。

html
<div id="demo-pagination-simple"></div>

<script>
  const pagination = new SaPagination('#demo-pagination-simple', {
    total: 100,
    pageSize: 10,
    current: 1,
    layout: 'prev, next',
    onChange: (page, pageSize) => {
      console.log('页码变化:', page, pageSize);
    }
  });
</script>
加载 SanoUI 组件中...
            
          

不同尺寸

通过 size 属性设置分页大小。

html
<!-- 大尺寸 -->
<div id="demo-pagination-large"></div>
<script>
  new SaPagination('#demo-pagination-large', {
    total: 100,
    pageSize: 10,
    size: 'large'
  });
</script>

<!-- 默认尺寸 -->
<div id="demo-pagination-default"></div>
<script>
  new SaPagination('#demo-pagination-default', {
    total: 100,
    pageSize: 10
  });
</script>

<!-- 小尺寸 -->
<div id="demo-pagination-small"></div>
<script>
  new SaPagination('#demo-pagination-small', {
    total: 100,
    pageSize: 10,
    size: 'small'
  });
</script>
加载 SanoUI 组件中...
            
          

API

构造函数参数

参数说明类型默认值
container容器选择器或元素string | HTMLElement-
options配置选项SaPaginationOptions{}

配置选项

参数说明类型可选值默认值
total总记录数number-0
pageSize每页条数number-10
currentPage当前页码number-1
layout布局string'total, prev, pager, next, jumper, sizes''prev, pager, next'
size尺寸stringlarge / default / smalldefault
pageSizes每页条数选项Array<number>-[10, 20, 50, 100]
pagerCount页码按钮数量(当总页数超过该值时会折叠)number-7
small是否小尺寸boolean-false
disabled是否禁用boolean-false
hideOnSinglePage只有一页时是否隐藏boolean-false
onChange页码变化回调function(page, pageSize): void-null
onPageSizeChange每页条数变化回调function(pageSize): void-null

方法

方法名说明参数返回值
setCurrentPage(page)设置当前页码page: numbervoid
setPageSize(pageSize)设置每页条数pageSize: numbervoid
setTotal(total)设置总记录数total: numbervoid
getCurrentPage()获取当前页码-number
getPageSize()获取每页条数-number
getTotal()获取总记录数-number
destroy销毁实例-void

自动初始化属性

属性说明类型默认值
class="sa-pagination"启用自动初始化--
data-pagination启用自动初始化标记boolean-
data-total总记录数number0
data-page-size每页条数number10
data-current当前页码number1
data-layout布局string'prev, pager, next'
data-size尺寸stringdefault

实际使用场景

场景 1:配合表格使用

分页组件与表格组件配合,实现数据分页展示。

html
<div id="pagination-table" style="height: 300px; margin-bottom: 1rem;"></div>
<div id="pagination-control" style="display: flex; justify-content: center;"></div>

<script>
  // 模拟数据
  const allData = Array.from({ length: 100 }, (_, i) => ({
    id: i + 1,
    name: `用户 ${i + 1}`,
    email: `user${i + 1}@example.com`
  }));
  
  let currentPage = 1;
  const pageSize = 10;
  
  const table = new SaTable('#pagination-table', {
    columns: [
      { field: 'id', label: 'ID', width: 80 },
      { field: 'name', label: '姓名', width: 150 },
      { field: 'email', label: '邮箱', width: 200 }
    ],
    data: [],
    bordered: true
  });
  
  const pagination = new SaPagination('#pagination-control', {
    total: allData.length,
    pageSize: pageSize,
    currentPage: currentPage,
    layout: 'total, sizes, prev, pager, next, jumper',
    onChange: (page, size) => {
      currentPage = page;
      loadTableData(page, size);
    },
    onPageSizeChange: (size) => {
      currentPage = 1;
      loadTableData(1, size);
    }
  });
  
  function loadTableData(page, size) {
    const start = (page - 1) * size;
    const end = start + size;
    const pageData = allData.slice(start, end);
    table.updateData(pageData, allData.length);
  }
  
  // 初始加载
  loadTableData(currentPage, pageSize);
</script>
加载 SanoUI 组件中...
            
          

场景 2:服务端分页

配合服务端 API 实现真正的服务端分页。

html
<div id="server-pagination-table" style="height: 300px; margin-bottom: 1rem;"></div>
<div id="server-pagination-control" style="display: flex; justify-content: center;"></div>

<script>
  let currentPage = 1;
  let currentPageSize = 10;
  let totalRecords = 0;
  
  const table = new SaTable('#server-pagination-table', {
    columns: [
      { field: 'id', label: 'ID', width: 80 },
      { field: 'title', label: '标题', width: 200 },
      { field: 'author', label: '作者', width: 120 },
      { field: 'createTime', label: '创建时间', width: 180 }
    ],
    data: [],
    bordered: true
  });
  
  const pagination = new SaPagination('#server-pagination-control', {
    total: 0,
    pageSize: currentPageSize,
    currentPage: currentPage,
    layout: 'total, sizes, prev, pager, next, jumper',
    onChange: async (page, size) => {
      currentPage = page;
      currentPageSize = size;
      await loadData(page, size);
    },
    onPageSizeChange: async (size) => {
      currentPage = 1;
      currentPageSize = size;
      await loadData(1, size);
    }
  });
  
  // 模拟服务端 API 调用
  async function loadData(page, size) {
    try {
      // 显示加载状态
      table._setState({ loading: true });
      
      // 模拟 API 调用延迟
      await new Promise(resolve => setTimeout(resolve, 500));
      
      // 模拟服务端返回的数据
      const mockData = Array.from({ length: 200 }, (_, i) => ({
        id: i + 1,
        title: `文章标题 ${i + 1}`,
        author: `作者 ${(i % 5) + 1}`,
        createTime: `2024-01-${String((i % 28) + 1).padStart(2, '0')} 10:00:00`
      }));
      
      totalRecords = mockData.length;
      const start = (page - 1) * size;
      const end = start + size;
      const pageData = mockData.slice(start, end);
      
      // 更新表格和分页
      table.updateData(pageData, totalRecords);
      pagination.setTotal(totalRecords);
      pagination.setCurrentPage(page);
      
      table._setState({ loading: false });
    } catch (error) {
      console.error('加载数据失败:', error);
      table._setState({ loading: false });
    }
  }
  
  // 初始加载
  loadData(currentPage, currentPageSize);
</script>
加载 SanoUI 组件中...
            
          

场景 3:动态更新总数

根据筛选条件动态更新分页的总数。

html
<div style="margin-bottom: 1rem;">
  <select id="status-filter" onchange="applyFilter()" style="padding: 0.5rem; border: 1px solid #ddd; border-radius: 4px;">
    <option value="">全部状态</option>
    <option value="active">正常</option>
    <option value="inactive">禁用</option>
  </select>
</div>

<div id="filter-table" style="height: 300px; margin-bottom: 1rem;"></div>
<div id="filter-pagination" style="display: flex; justify-content: center;"></div>

<script>
  // 所有数据
  const allData = [
    ...Array.from({ length: 50 }, (_, i) => ({ id: i + 1, name: `用户 ${i + 1}`, status: 'active' })),
    ...Array.from({ length: 30 }, (_, i) => ({ id: 51 + i, name: `用户 ${51 + i}`, status: 'inactive' }))
  ];
  
  let filteredData = allData;
  let currentPage = 1;
  const pageSize = 10;
  
  const table = new SaTable('#filter-table', {
    columns: [
      { field: 'id', label: 'ID', width: 80 },
      { field: 'name', label: '姓名', width: 150 },
      { field: 'status', label: '状态', width: 100 }
    ],
    data: [],
    bordered: true
  });
  
  const pagination = new SaPagination('#filter-pagination', {
    total: filteredData.length,
    pageSize: pageSize,
    currentPage: currentPage,
    layout: 'total, prev, pager, next',
    onChange: (page) => {
      currentPage = page;
      loadPageData();
    }
  });
  
  function applyFilter() {
    const status = document.getElementById('status-filter').value;
    
    if (status) {
      filteredData = allData.filter(item => item.status === status);
    } else {
      filteredData = allData;
    }
    
    // 重置到第一页并更新总数
    currentPage = 1;
    pagination.setTotal(filteredData.length);
    pagination.setCurrentPage(1);
    loadPageData();
  }
  
  function loadPageData() {
    const start = (currentPage - 1) * pageSize;
    const end = start + pageSize;
    const pageData = filteredData.slice(start, end);
    table.updateData(pageData, filteredData.length);
  }
  
  // 初始加载
  loadPageData();
</script>
加载 SanoUI 组件中...
            
          

场景 4:简单分页导航

只显示上一页和下一页按钮的简单分页。

html
<div id="simple-pagination" style="display: flex; justify-content: center;"></div>

<script>
  const simplePagination = new SaPagination('#simple-pagination', {
    total: 100,
    pageSize: 10,
    currentPage: 1,
    layout: 'prev, next',
    onChange: (page) => {
      console.log('跳转到第', page, '页');
      // 这里可以加载对应页的数据
    }
  });
</script>
加载 SanoUI 组件中...
            
          

场景 5:禁用状态

在加载数据时禁用分页组件,防止重复操作。

html
<div id="disabled-pagination" style="display: flex; justify-content: center; margin-bottom: 1rem;"></div>
<button class="sa-button sa-button--primary" onclick="toggleLoading()">切换加载状态</button>

<script>
  const pagination = new SaPagination('#disabled-pagination', {
    total: 100,
    pageSize: 10,
    currentPage: 1,
    layout: 'total, prev, pager, next, jumper',
    disabled: false,
    onChange: (page) => {
      console.log('页码变化:', page);
    }
  });
  
  let isLoading = false;
  
  function toggleLoading() {
    isLoading = !isLoading;
    pagination.config.disabled = isLoading;
    pagination._render();
    
    if (isLoading) {
      console.log('分页已禁用');
    } else {
      console.log('分页已启用');
    }
  }
</script>
加载 SanoUI 组件中...
            
          

注意事项

  1. 页码计算:总页数 = Math.ceil(total / pageSize)
  2. 布局配置layout 可以包含 total, sizes, prev, pager, next, jumper 的组合
  3. 单页隐藏:设置 hideOnSinglePage: true 时,只有一页数据会自动隐藏分页组件
  4. 页码按钮数量:通过 pagerCount 控制显示的页码按钮数量,超出时会折叠
  5. 事件回调onChange 在页码或每页条数变化时都会触发

常见问题

Q: 如何获取当前页码和每页条数?

A: 使用 getCurrentPage()getPageSize() 方法:

javascript
const currentPage = pagination.getCurrentPage();
const pageSize = pagination.getPageSize();

Q: 如何动态更新总数?

A: 使用 setTotal() 方法:

javascript
pagination.setTotal(newTotal);

Q: 如何跳转到指定页?

A: 使用 setCurrentPage() 方法:

javascript
pagination.setCurrentPage(5); // 跳转到第 5 页

Q: 如何自定义每页条数选项?

A: 通过 pageSizes 配置:

javascript
const pagination = new SaPagination('#pagination', {
  pageSizes: [5, 10, 20, 50, 100]
});

Q: 如何实现服务端分页?

A: 在 onChange 回调中调用 API:

javascript
const pagination = new SaPagination('#pagination', {
  onChange: async (page, pageSize) => {
    const response = await fetch(`/api/data?page=${page}&pageSize=${pageSize}`);
    const result = await response.json();
    // 更新表格数据
    table.updateData(result.data, result.total);
    // 更新分页总数
    pagination.setTotal(result.total);
  }
});

Q: 如何隐藏单页时的分页组件?

A: 设置 hideOnSinglePage: true

javascript
const pagination = new SaPagination('#pagination', {
  hideOnSinglePage: true
});

Released under the MIT License.