使用React+Mockjs开发自适应伸缩列表分页组件
项目预览
项目技术栈
create-react-app
脚手架express
后台服务,跨域设置,模拟数据库limit
操作mockjs
根据指定数据结构生成随机数据
项目目录src
目录
| App.css
| App.js
| index.js
|
+---components
+---Pagination
| Pagination.css
| Pagination.js
|
\---Posts
Posts.css
Posts.js
后台服务
在项目目录server
下新建server.js
核心逻辑如下:
// 获取文章列表
app.get('/posts', (req, res) => {
let posts_data = [];
for(let i=0;i<100;i++){
posts_data.push(
Mock.mock({
id: i+1,
title: Random.cparagraph(1),
content: Random.cparagraph(2,5),
author: Random.cname(),
time: Random.datetime('yyyy-MM-dd hh:mm:ss'),
'like|1-1000': 1
})
)
}
// 获取当前页数 以及 每页展示的条数
let perPageNumber = Number(req.query.perPageNumber ? req.query.perPageNumber : 10);
let currentPage = Number(req.query.currentPage ? req.query.currentPage : 1);
let totalPage = Math.ceil(posts_data.length/perPageNumber)
// 模拟数据库操作 limit 截取数组中对应的数据
let start = (currentPage-1)*perPageNumber
let end = perPageNumber*(currentPage) <= posts_data.length ? perPageNumber*(currentPage): posts_data.length
posts_data = posts_data.slice(start, end )
res.json({ content: posts_data, currentPage, totalPage })
})
前端展示核心部分
pagination/pagination.js 涉及自动变换分页的形态改变逻辑
import React from 'react'
import './Pagination.css'
const Pagination = ({ totalPage, currentPage, requestPostsByPage }) => {
let liArr = []
let allPageArr = []
let max = 10
for(let i=0;i<totalPage;i++){
allPageArr.push(i+1)
}
// 首先判断总页数 当总页数小于10时
if(allPageArr.length <= max){ //[...allPageArr.slice(0,max-3),'…', ...allPageArr.slice(-2)]
liArr = allPageArr
}else{
// 当总页数大于10 当前页小于5时
if( currentPage < 5 ){
liArr = [...allPageArr.slice(0,5),'…', totalPage]
}else{
// 当总页数大于10 当前页小于 totalPage-5 时
if(currentPage <= totalPage-5){
liArr = [1, '…', ...allPageArr.slice(currentPage-1,currentPage+2),'…', totalPage]
}else{ // 当总页数大于10 当前页大于 totalPage-5 时
liArr = [1, '…', ...allPageArr.slice(totalPage-5, totalPage)]
}
}
}
return (
<nav>
<ul className="list-pages">
<li className="list-pages-item" onClick={() => requestPostsByPage(currentPage-1)}><</li>
{ liArr.map( (v,index) => (
<li className={ v !== '…' ? ( currentPage === v ? "list-pages-item list-pages-item-active": 'list-pages-item' ): '' } key={index} onClick={() => requestPostsByPage(v)}>
{ v }
</li>
))}
<li className="list-pages-item" onClick={() => requestPostsByPage(currentPage+1)}>></li>
</ul>
</nav>
)
}
export default Pagination
src/App.js 涉及state
定义,分发处理
const [posts, setPosts] = useState([])
const [loading, setLoading] = useState(false)
const [currentPage, setCurrentPage] = useState(10)
const [totalPage, setTotalPage] = useState(1)
const [perPageNumber, setPerPageNumber] = useState(3)
useEffect(() => {
const requestPosts = async () => {
setLoading(true);
const res = await axios.get('http://localhost:3001/posts', { params: { currentPage, perPageNumber } } )
setPosts(res.data.content)
setTotalPage(res.data.totalPage)
setLoading(false);
}
// 调用请求
requestPosts()
}, [currentPage, perPageNumber])
// console.log(posts)
const requestPostsByPage = (v) => {
if(v !== '…'){
// 边界处理
if( v === 0 || v > totalPage) return;
setCurrentPage(v)
}
}