1. 在后端接口做分页处理
API:
@server.route("/api/get_container2", methods=['get'])
def get_container2():
"""
images2 --- center
"""
sql = mysql.fetchall("select * from xysh_imgs2 where is_delete = '0' order by text2 desc")
page = request.args.get('page', 1, type=int) # 默认页码为1
limit = request.args.get('limit', 6, type=int) # 默认每页显示10条记录
page = max(1, page)
limit = max(1, limit)
total_count = len(sql) # 计算图片总数
total_pages = (total_count + limit - 1) // limit # 计算总页数
start_index = (page - 1) * limit
end_index = start_index + limit
page_data = sql[start_index:min(end_index, len(sql))]
return {"data": page_data, "total_pages": total_pages}
前端:
const [currentPage, setCurrentPage] = useState(1)
const [IMAGE2,setImage2] = useState([])
const [totalPages, setTotalPages] = useState<number | null>(null);
const [pageNumbers, setPageNumbers] = useState<number[]>([]);
const fetchData = async (page : number) => {
await new Promise(resolve => {setTimeout(resolve, 300)})
try {
const response = await get_container2({ page });
const { data, total_pages } = response;
setImage2(data);
setTotalPages(total_pages);
if (total_pages !== null) {
const newPageNumbers = Array.from({ length: total_pages }, (_, i) => i + 1);
setPageNumbers(newPageNumbers);
}
} catch (error) {
console.error('Error fetching images:', error);
}
};
// 翻页的逻辑
useEffect(() => {
fetchData(currentPage);
}, [currentPage]);
const handlePreviousPage = () => {
if (currentPage > 1) {
setCurrentPage(currentPage - 1);
}
};
const handleNextPage = () => {
if (totalPages !== null && currentPage < totalPages) {
setCurrentPage(currentPage + 1);
}
};
const handlePageClick = (pageNumber: number) => {
if (totalPages !== null && pageNumber >= 1 && pageNumber <= totalPages) {
setCurrentPage(pageNumber);
}
};
const isPreviousDisabled = currentPage === 1;
const isNextDisabled = totalPages !== null && currentPage === totalPages;
按钮点击事件:
<div className={'FlipPage'}>
<ConfigProvider
theme={{
components: {
Button: {
defaultBg: "#ffffff",
defaultBorderColor: "#ccc"
},
},
}}>
<Button onClick={handlePreviousPage} disabled={isPreviousDisabled} shape="round" size={"large"} className={'button-l'}>prey</Button>
{pageNumbers.map((pageNumber) => (
<Button
key={pageNumber}
onClick={() => handlePageClick(pageNumber)}
disabled={currentPage === pageNumber}
shape="round"
size="large"
className={currentPage === pageNumber ? 'button-active' : 'button-page'}
>
{pageNumber}
</Button>
))}
<Button onClick={handleNextPage} disabled={isNextDisabled} shape="round" size={"large"} className={'button-r'}>next</Button>
</ConfigProvider>
</div>
CSS:
/*翻页按钮的CSS样式*/
.FlipPage {
margin-bottom: 30px;
text-align: center;
}
.button-l {
position: absolute;
left: 0;
font-size: 18px;
width: 140px;
height: 50px;
transition: all .4s ease-in-out;
}
.button-l::before {
content: '';
width: 12px;
height: 14px;
position: absolute;
left: 20%;
top: 50%;
transform: translateY(-40%);
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAFsus16AAAACXBIWXMAAAsTAAALEwEAmpwYAAAF8WlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIyLTA3LTE4VDE4OjM1OjMxKzA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMi0wNy0xOFQyMDowNCswODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMi0wNy0xOFQyMDowNCswODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDowNjkxNWQ1MS00ZjdkLWYxNGQtYTQ1NC05ZjdjYWI5YzA1MzciIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDo5Mzk3NTA5Yy02ZGI4LTBlNDQtYjE1OC0zZDA2ZWU2NjYxZmYiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpkZWMyODZkNC05MWNiLTJjNDYtYjM1YS1hNzQ4NGQ4YWNhYmYiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmRlYzI4NmQ0LTkxY2ItMmM0Ni1iMzVhLWE3NDg0ZDhhY2FiZiIgc3RFdnQ6d2hlbj0iMjAyMi0wNy0xOFQxODozNTozMSswODowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDowNjkxNWQ1MS00ZjdkLWYxNGQtYTQ1NC05ZjdjYWI5YzA1MzciIHN0RXZ0OndoZW49IjIwMjItMDctMThUMjA6MDQrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4ENtFkAAAAqUlEQVQokW3RSZLCMBBE0SeF78P5wA0eGPoAHNi9EBVdIVQ7Z+ZXpazi9IajalM4vVUcJTyU5P87C9aKGWvEHthhinwDGwPXSKBMOOOVNoCK3yQc2PqjwoCtjsTo+CVGxRDXOD+WP5IhG7n/kQ3aT9my2deNueV9udjUiT+4j4LxEcCcSg+DGXji0un7KEy73Ky9Rd5wk96lB2KuH3BP2heYgZjlAy4j8A9gvC8MEaYeDAAAAABJRU5ErkJggg==);
transition: all .4s ease-in-out;
}
.button-l:hover {
background-color: #002f93 !important;
color: #ffff !important;
}
.button-l:hover::before {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAFsus16AAAACXBIWXMAAAsTAAALEwEAmpwYAAAF+mlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoV2luZG93cykiIHhtcDpDcmVhdGVEYXRlPSIyMDIyLTA3LTE4VDE4OjM1OjA1KzA4OjAwIiB4bXA6TW9kaWZ5RGF0ZT0iMjAyMi0wNy0xOFQyMDowNDoxMyswODowMCIgeG1wOk1ldGFkYXRhRGF0ZT0iMjAyMi0wNy0xOFQyMDowNDoxMyswODowMCIgZGM6Zm9ybWF0PSJpbWFnZS9wbmciIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo3YWE0NWQ3ZS1mNzk5LTJlNGUtYTY3YS1hNGQyMzg3OTA5ZDMiIHhtcE1NOkRvY3VtZW50SUQ9ImFkb2JlOmRvY2lkOnBob3Rvc2hvcDowNDlkMDllYi1kOWQwLTgwNDUtYWE5Yy04MmVjYTA0M2EzOTAiIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDplMmE5MTgwYi01YWIwLThjNDEtODc4ZC05ZGQ1ZWE2ZWI5MTYiPiA8eG1wTU06SGlzdG9yeT4gPHJkZjpTZXE+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJjcmVhdGVkIiBzdEV2dDppbnN0YW5jZUlEPSJ4bXAuaWlkOmUyYTkxODBiLTVhYjAtOGM0MS04NzhkLTlkZDVlYTZlYjkxNiIgc3RFdnQ6d2hlbj0iMjAyMi0wNy0xOFQxODozNTowNSswODowMCIgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWRvYmUgUGhvdG9zaG9wIENDIDIwMTkgKFdpbmRvd3MpIi8+IDxyZGY6bGkgc3RFdnQ6YWN0aW9uPSJzYXZlZCIgc3RFdnQ6aW5zdGFuY2VJRD0ieG1wLmlpZDo3YWE0NWQ3ZS1mNzk5LTJlNGUtYTY3YS1hNGQyMzg3OTA5ZDMiIHN0RXZ0OndoZW49IjIwMjItMDctMThUMjA6MDQ6MTMrMDg6MDAiIHN0RXZ0OnNvZnR3YXJlQWdlbnQ9IkFkb2JlIFBob3Rvc2hvcCBDQyAyMDE5IChXaW5kb3dzKSIgc3RFdnQ6Y2hhbmdlZD0iLyIvPiA8L3JkZjpTZXE+IDwveG1wTU06SGlzdG9yeT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz74oLWoAAAAq0lEQVQokW3RW5LCMBBD0WNXNsXShgB5kBl2ww6pzEfoosu4/yLpuuW4vJ4n2KtjitfzpGIv4aF8/ORMmCtGzBHbsMIQeQgGrpFAGfCDv7QBVDySsGNpjwoDltoTo+OXGBVDnOP8WL4lQzZy/z0bHD9lyWZbN+aW9+ViQyNecO8F4yOAMZXuBjPwi3Ojr70wx+VGx1vkDTfpXVog5voG16R9gRmImd7g1AP/Abh7Nvr5qnPSAAAAAElFTkSuQmCC);
}
.button-r {
position: absolute;
right: 0;
font-size: 18px;
width: 140px;
height: 50px;
transition: all .4s ease-in-out;
}
.button-r::before {
content: '';
width: 12px;
height: 14px;
position: absolute;
right: 20%;
top: 50%;
transform: translateY(-40%);
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAAbvf3sAAAAj0lEQVQokYXSyQ1CMQyE4f8BRwqgC1p4cKQlxPZEBzTE0hVi00hESqwx+JLIni+XuGN+2gM72lLvgKkxs9UZ6IC+Guv+Bi6RCOh0aAG8gKsDv9CzRjXI0BJ4ADcH/iIHCsKg+8ilv+Vm0wzoD7ahdwTWDmThjS4RuPBQwhFk4WZtCnBh9eKOMUnCCur1toAP87Uif6QrvmgAAAAASUVORK5CYII=);
transition: all .4s ease-in-out;
}
.button-r:hover {
background-color: #002f93 !important;
color: #ffff !important;
}
.button-r:hover::before {
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAOCAYAAAAbvf3sAAAAkklEQVQokY2SzQ3CMAxGX1uOrMAg3NopGAbRAu08nQHYqz8yaqQk+lzVF0fOe7FlpZjG6xPoSMNqL0RU3e3yAQqgjq7tvADfXDHBspIaYAZ+StiTplgqD8zeA3dP8KQhSCe1iU1athxLs+qw1/3sCTZSq8ZSggc/VFsFvwOcCx6cfJsgKNhq+R/7r1XBBtrraQArYOsjbdwjVQMAAAAASUVORK5CYII=);
}
2. 在前端调用接口做处理
前端:
const [currentPage, setCurrentPage] = useState(1);
const [allImages, setAllImages] = useState([]);
const [currentImages, setCurrentImages] = useState([]);
const [limit] = useState(9); // 设置每页显示的图片数量
const fetchAllImages = async () => {
try {
const response = await get_container2({});
const { data} = response;
setAllImages(data);
setCurrentImages(data.slice(0, limit)); // 显示第一页的图片
setCurrentPage(1);
} catch (error) {
console.error('Error fetching images:', error);
}
};
useEffect(() => {
fetchAllImages();
}, []);
// 更新当前页显示的图片
const updateCurrentImages = (page: number) => {
const startIndex = (page - 1) * limit;
const endIndex = Math.min(startIndex + limit, allImages.length);
setCurrentImages(allImages.slice(startIndex, endIndex));
};
// 上一页 按钮的逻辑
const handlePreviousPage = () => {
if (currentPage > 1) {
setCurrentPage(currentPage - 1);
updateCurrentImages(currentPage - 1);
}
};
// 下一页 按钮的逻辑
const handleNextPage = () => {
if (currentPage < Math.ceil(allImages.length / limit)) {
setCurrentPage(currentPage + 1);
updateCurrentImages(currentPage + 1);
}
};
// 中间数字点击的逻辑
const handlePageClick = (pageNumber: number) => {
if (pageNumber >= 1 && pageNumber <= Math.ceil(allImages.length / limit)) {
setCurrentPage(pageNumber);
updateCurrentImages(pageNumber);
}
};
// 上一页`下一页按钮置灰的逻辑
const isPreviousDisabled = currentPage === 1;
const isNextDisabled = currentPage >= Math.ceil(allImages.length / limit);
// 中间数字页面的按钮
const renderPageNumbers = () => {
if (!allImages.length) return null; // 如果没有图片数据,则不显示页码
const totalPages = Math.ceil(allImages.length / limit);
const pageButtons = [];
for (let i = 1; i <= totalPages; i++) {
pageButtons.push(
<Button
key={`page-${i}`}
onClick={() => handlePageClick(i)}
disabled={currentPage === i} // 当前页码按钮不可点击
shape="round"
size="large"
>
{i}
</Button>
);
}
return pageButtons;
};
// 上一页`下一页按钮
const renderPaginationButtons = () => (
<div className={'FlipPage'}>
<ConfigProvider
theme={{
components: {
Button: {
defaultBg: "#ffffff",
defaultBorderColor: "#ccc"
},
},
}}>
<Button onClick={handlePreviousPage} disabled={isPreviousDisabled} shape="round" size={"large"} className={'button-l'}>prey</Button>
{renderPageNumbers()}
<Button onClick={handleNextPage} disabled={isNextDisabled} shape="round" size={"large"} className={'button-r'}>next</Button>
</ConfigProvider>
</div>
);
这里的CSS与上方的CSS一样。
·在页面将 renderPaginationButtons 调用即可·
后端:
@server.route("/api/get_container2", methods=['get'])
def get_container2():
"""
第二组图片的接口,返回所有数据
"""
sql = mysql.fetchall("select * from xysh_imgs2 where is_delete = '0' order by text2 desc")
return { "data": sql, "total_count": len(sql) }