介绍
在这个项目中,你将学习如何构建一个分页组件,这是 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 函数来处理数据请求。
- 打开
js/index.js文件。 - 找到
ajax函数并完成其实现。 ajax函数应根据函数参数获取当前页面的数据和总页数,并返回这些数据。- 你可以使用提供的 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 函数,该函数用于为分页组件的按钮绑定事件。
- 打开
js/index.js文件。 - 找到
initEvents函数并完成其实现。 - 当点击“<”按钮时,
this.currentPage的值应减 1,但最小为 1。 - 当点击“>”按钮时,
this.currentPage的值应加 1,但最大为this.totalPages。 - 当
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)。
打开
js/util.js文件。找到
createPaginationIndexArr函数并完成其实现。该函数应根据传入的参数
currentPage、totalPages和pagerCount生成分页数组(indexArr)。生成分页数组的规则如下:
- 特殊情况:
totalPages <= pagerCount - 一般情况:
totalPages > pagerCount
- 特殊情况:
生成的
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。
- 打开
js/index.js文件。 - 找到
renderPagination函数并完成其实现。 - 该函数应根据
indexArr数组,按照挑战描述中所述的规则,为分页组件生成字符串模板template。 - 生成的
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"><</div>
<ul class="pager">${template} </ul>
<div class="btn btn-right" id="btn-next">></div>
</div>`;
}
测试分页组件
在这一步中,你将测试分页组件的最终结果。
- 保存
js/index.js和js/util.js文件。 - 在浏览器中刷新网页。
- 检查页面效果。
恭喜你!你已经完成了分页组件的实现。最终的页面效果应如下所示:

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



