You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何实现可前后切换的3列Person卡片滑块?

实现人员卡片横向分页切换方案

需求回顾

现有PersonList组件通过map渲染所有Person卡片,需改为横向排列、每次显示3张,支持「向前」「向后」按钮切换分页。

具体实现步骤

  • 为PersonList添加状态管理,控制当前显示的起始索引
  • 根据起始索引截取对应3条人员数据进行渲染
  • 实现分页按钮的点击逻辑,处理边界限制(避免超出数组范围)
  • 通过CSS Flex布局实现卡片横向排列,容器设置溢出隐藏确保仅显示3张

修改后的完整代码

PersonList组件代码

import { useState } from 'react';
import Person from '../person/Person';
import './personList.css';
import { personArr } from '../helpers/personList';

const PersonList = () => {
  // 控制当前显示的起始索引,初始为0
  const [startIndex, setStartIndex] = useState(0);
  // 每页显示数量
  const pageSize = 3;

  // 向前切换分页
  const handlePrev = () => {
    if (startIndex > 0) {
      setStartIndex(prev => prev - pageSize);
    }
  };

  // 向后切换分页
  const handleNext = () => {
    if (startIndex + pageSize < personArr.length) {
      setStartIndex(prev => prev + pageSize);
    }
  };

  // 获取当前分页要显示的人员数据
  const currentPersons = personArr.slice(startIndex, startIndex + pageSize);

  return (
    <div className="list_container">
      {/* 分页控制按钮 */}
      <button className="pagination-btn" onClick={handlePrev} disabled={startIndex === 0}>
        向前
      </button>

      {/* 卡片容器 */}
      <div className="list_wrapper">
        {currentPersons.map((el, i) => (
          <Person
            key={`${el.name}-${i}`} {/* 用唯一标识组合代替纯索引,避免渲染异常 */}
            name={el.name}
            post={el.post}
            img={el.img}
            exp={el.exp}
          />
        ))}
      </div>

      <button className="pagination-btn" onClick={handleNext} disabled={startIndex + pageSize >= personArr.length}>
        向后
      </button>
    </div>
  );
};

export default PersonList;

personList.css样式代码

/* 外层容器:放置按钮和卡片区域 */
.list_container {
  display: flex;
  align-items: center;
  gap: 1rem;
  max-width: 1200px;
  margin: 0 auto;
  padding: 1rem;
}

/* 卡片容器:横向排列+隐藏溢出 */
.list_wrapper {
  display: flex;
  gap: 1rem;
  overflow: hidden;
  flex: 1;
}

/* 单个人员卡片:固定宽度,确保3张占满一行 */
.person_wrapper {
  flex: 0 0 calc(33.333% - 0.666rem);
  box-sizing: border-box;
  border: 1px solid #eee;
  border-radius: 8px;
  padding: 1rem;
  transition: transform 0.3s ease;
}

.person_img img {
  width: 100%;
  height: auto;
  border-radius: 8px;
}

.person_text {
  text-align: center;
  margin-top: 1rem;
}

/* 分页按钮样式 */
.pagination-btn {
  padding: 0.5rem 1rem;
  border: none;
  border-radius: 4px;
  background-color: #007bff;
  color: white;
  cursor: pointer;
}

.pagination-btn:disabled {
  background-color: #ccc;
  cursor: not-allowed;
}

Person组件(无需修改,保持原代码即可)

const Person = ({name, exp, post, img}) => {
  return (
    <div className="person_wrapper">
      <div className="person_img">
        <img src={img} alt={name} />
      </div>
      <div className="person_text">
        <h2 className="person_name"> {name} </h2>
        <p className="person_post"> {post} </p>
        <p className="person_exp"> {exp} </p>
      </div>
    </div>
  );
};

export default Person;

内容的提问来源于stack exchange,提问作者Nikolai

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 03:42:14