构建可复用的分页组件

JavaScriptJavaScriptBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

简介

在这个项目中,你将学习如何构建一个分页组件,这是 Web 应用程序中常用的组件。分页组件有助于减少后端的查询时间,并且不会因加载过多数据而影响页面渲染性能。

👀 预览

分页组件演示

🎯 任务

在这个项目中,你将学习:

  • 如何实现 ajax 函数来处理数据请求,并获取当前页面的数据和总页数。
  • 如何实现 initEvents 函数来为分页组件的按钮绑定事件。
  • 如何实现 createPaginationIndexArr 函数,根据函数参数生成一个分页数组。
  • 如何实现 renderPagination 函数来生成分页组件的字符串模板。
  • 如何根据当前页面渲染内容。

🏆 成果

完成这个项目后,你将能够:

  • 用 JavaScript 构建一个可复用的分页组件。
  • 使用 Axios 进行 HTTP 请求并处理响应数据。
  • 根据当前页面、总页数和要显示的最大页码按钮数生成一个分页数组。
  • 根据当前页面更新分页组件和内容。

设置项目结构

在这一步中,你将设置项目文件和结构。请按照以下步骤完成此步骤:

打开项目文件夹。目录结构如下:

├── css
│   └── index.css
├── index.html
└── js
    ├── data.json
    ├── axios.min.js
    ├── util.js
    └── index.js

其中:

  • css/index.css 是 CSS 样式文件。
  • index.html 是主页。
  • js/data.json 是存储数据的 JSON 文件。
  • js/axios.min.js 是 axios 文件。
  • js/index.js 是要完成的文件。
  • js/util.js 是存储实用函数的文件。

点击 WebIDE 右下角的 Go Live 按钮来运行项目。

接下来,在 VM 顶部打开“Web 8080”并手动刷新以查看页面。

初始效果

实现 ajax 函数

在这一步中,你将在 js/index.js 文件中实现 ajax 函数来处理数据请求。

  1. 打开 js/index.js 文件。
  2. 找到 ajax 函数并完成其实现。
  3. ajax 函数应根据函数参数获取当前页面的数据和总页数,并返回这些数据。
  4. 你可以使用提供的 Axios 库向 ./js/data.json 文件发送 HTTP 请求。

以下是完整的 ajax 函数:

async function ajax({
  url,
  method = "get",
  data,
  query: { currentPage, pageSize }
}) {
  // TODO: 根据函数参数 `query` 对象中的 `currentPage` 和 `pageSize` 获取当前页面的数据。
  let result = {
    data: [],
    total: 0
  };

  let resData = [];
  let res = await axios[method](url, data);
  if (res.status === 200) {
    resData = res.data.data;
    result.total = res.data.total;
  }
  result.data = resData.slice(
    (currentPage - 1) * pageSize,
    currentPage * pageSize
  );

  return result;
}

实现 initEvents 函数

在这一步中,你将在 js/index.js 文件中实现 initEvents 函数,该函数用于为分页组件的按钮绑定事件。

  1. 打开 js/index.js 文件。
  2. 找到 initEvents 函数并完成其实现。
  3. 当点击“<”按钮时,this.currentPage 的值应减 1,但最小为 1。
  4. 当点击“>”按钮时,this.currentPage 的值应加 1,但最大为 this.totalPages
  5. this.currentPage 的值发生变化时,页面上的分页组件应相应更新。

以下是完整的 initEvents 函数:

initEvents() {
    this.root.querySelector("#btn-prev").addEventListener("click", () => {
      // TODO: “<”按钮的点击事件,点击时 `this.currentPage - 1`。
      if (this.currentPage > 1) {
        this.currentPage--;
        this.initPagination();
      }
    });
    this.root.querySelector("#btn-next").addEventListener("click", () => {
      // TODO: “>”按钮的点击事件,点击时 `this.currentPage + 1`。
      if (this.currentPage < this.totalPages) {
        this.currentPage++;
        this.initPagination();
      }
    });
    this.root.querySelector(".pager").addEventListener("click", (e) => {
      if (e.target.nodeName.toLowerCase() === "li") {
        if (this.currentPage === e.target.innerText) return;
        if (e.target.classList.contains("more")) return;
        this.currentPage = Number(e.target.innerText);
      }
      this.initPagination();
    });
  }

实现 createPaginationIndexArr 函数

在这一步中,你将在 js/util.js 文件中实现 createPaginationIndexArr 函数,该函数会根据特定规则基于函数参数生成一个分页数组(indexArr)。

  1. 打开 js/util.js 文件。

  2. 找到 createPaginationIndexArr 函数并完成其实现。

  3. 该函数应根据传入的参数 currentPagetotalPagespagerCount 生成分页数组(indexArr)。

  4. 生成分页数组的规则如下:

    • 特殊情况:totalPages <= pagerCount
    • 一般情况:totalPages > pagerCount
  5. 生成的 indexArr 应遵循挑战描述中提供的示例。

以下是完整的 createPaginationIndexArr 函数:

const createPaginationIndexArr = (currentPage, totalPages, pagerCount) => {
  let indexArr = [];
  // TODO: 根据传入参数生成分页数组 indexArr。
  indexArr[0] = 1;
  if (totalPages <= pagerCount) {
    for (let i = 1; i < totalPages; i++) {
      indexArr.push(i + 1);
    }
  } else {
    indexArr[pagerCount - 1] = totalPages;
    if (currentPage <= pagerCount - 2) {
      for (let i = 1; i < pagerCount - 1; i++) {
        indexArr[i] = i + 1;
      }
    } else if (currentPage <= totalPages - pagerCount + 2) {
      let j = 1;
      for (
        let i = -Math.ceil((pagerCount - 3) / 2);
        i <= Math.floor((pagerCount - 3) / 2);
        i++
      ) {
        indexArr[j++] = currentPage + i;
      }
    } else {
      let j = 1;
      for (let i = totalPages - pagerCount + 2; i < totalPages; i++) {
        indexArr[j++] = i;
      }
    }
  }

  return indexArr;
};

实现 renderPagination 函数

在这一步中,你将在 js/index.js 文件中实现 renderPagination 函数,该函数会根据 indexArr 数组为分页组件生成字符串模板 template

  1. 打开 js/index.js 文件。
  2. 找到 renderPagination 函数并完成其实现。
  3. 该函数应根据 indexArr 数组,按照挑战描述中所述的规则,为分页组件生成字符串模板 template
  4. 生成的 template 应使用 this.root.innerHTML 插入到分页组件的 HTML 结构中。

以下是完整的 renderPagination 函数:

renderPagination(indexArr) {
  let template = "";
  // TODO: 根据 indexArr 数组为分页组件生成字符串模板 template。
  template = indexArr.reduce((prev, next, index) => {
    if (indexArr[index] - indexArr[index - 1] > 1) {
      prev += `<li class="number more">...</li>`;
      prev += `<li class="number ${
        this.currentPage == next? "active" : ""
      }">${next}</li>`;
    } else {
      prev += `<li class="number ${
        this.currentPage == next? "active" : ""
      }">${next}</li>`;
    }
    return prev;
  }, "");

  this.root.innerHTML = `
      <div class="pagination">
          <div class="btn btn-left" id="btn-prev">&lt;</div>
          <ul class="pager">${template} </ul>
          <div class="btn btn-right" id="btn-next">&gt;</div>
      </div>`;
}

测试分页组件

在这一步中,你将测试分页组件的最终结果。

  1. 保存 js/index.jsjs/util.js 文件。
  2. 在浏览器中刷新网页。
  3. 检查页面效果。

恭喜你!你已经完成了分页组件的实现。最终的页面效果应如下所示:

图片描述
✨ 查看解决方案并练习

总结

恭喜你!你已经完成了这个项目。你可以在 LabEx 中练习更多实验来提升你的技能。