React 基础案例 | 支持左右按钮点击查看信息的卡片组件(二)
共 10436字,需浏览 21分钟
·
2021-08-01 10:26
一、开篇
大家好,本篇文章小编将和大家一起实现一个用左右点击的方式翻看卡片信息的组件,这个组件很常用,一般会在网站上显示案例或团队成员的信息。通过本案例我们继续练习 useState Hook 在实际案例场景中的应用。
二、案例展示
如下视频所示,一个展示个人信息的卡片,我们可以点击卡片下方的左右按钮进行切换卡片的信息,用户的信息循环展示(信息数组的两端头尾连接循环),同时加了一个随机显示的按钮,点击按钮随机显示用户的信息。
三、创建项目
开始之前,我们通过 create-react-app 命令创建项目文件夹 reviews,接下来删除一些不相关的文件,保留 App.js、index.css、index.js,index.js 文件内容如下:
import React from 'react';
import Review from './Review';
function App() {
return (
<main>
<section className="container">
<div className="title">
<h2>our reviews</h2>
<div className='underline'></div>
</div>
<Review/>
</section>
</main>
);
}
export default App;
//src/app.js
从上述代码你可以看出我们引入了 Review 卡片组件,也是本案例的核心,稍后我会介绍到。
四、设计本地数据结构
展示信息,需要有相关的数据,本案例将用本地文件数据。本地的数据结构比较简单,一个数组对象,包含 id、name(姓名)、job(岗位)、image(头像)、text(介绍),接下来我们新建一个 data.js 的文件,定义 reviews 对象变量,代码示例如下:
const reviews = [
{
id: 1,
name: 'susan smith',
job: 'web developer',
image:
'https://res.cloudinary.com/diqqf3eq2/image/upload/v1586883334/person-1_rfzshl.jpg',
text:
"I'm baby meggings twee health goth +1. Bicycle rights tumeric chartreuse before they sold out chambray pop-up. Shaman humblebrag pickled coloring book salvia hoodie, cold-pressed four dollar toast everyday carry",
},
...
];
export default reviews;
// src/data.js
五、完善CSS文件
基于页面,我们新建 index.css 文件,定义卡片的展示样式,示例代码如下,由于代码比较简单,这里就不过多解释了,这里只展示卡片的基础样式,完整代码,请查看文末获取方式。
/*
===============
Variables
===============
* 省略/
....
/*
===============
Reviews
===============
*/
main {
min-height: 100vh;
display: grid;
place-items: center;
}
.title {
text-align: center;
margin-bottom: 4rem;
}
.underline {
height: 0.25rem;
width: 5rem;
background: var(--clr-primary-5);
margin-left: auto;
margin-right: auto;
}
.container {
width: 80vw;
max-width: var(--fixed-width);
}
.review {
background: var(--clr-white);
padding: 1.5rem 2rem;
border-radius: var(--radius);
box-shadow: var(--light-shadow);
transition: var(--transition);
text-align: center;
}
.review:hover {
box-shadow: var(--dark-shadow);
}
.img-container {
position: relative;
width: 150px;
height: 150px;
border-radius: 50%;
margin: 0 auto;
margin-bottom: 1.5rem;
}
.person-img {
width: 100%;
display: block;
height: 100%;
object-fit: cover;
border-radius: 50%;
position: relative;
}
.quote-icon {
position: absolute;
top: 0;
left: 0;
width: 2.5rem;
height: 2.5rem;
display: grid;
place-items: center;
border-radius: 50%;
transform: translateY(25%);
background: var(--clr-primary-5);
color: var(--clr-white);
}
.img-container::before {
content: '';
width: 100%;
height: 100%;
background: var(--clr-primary-5);
position: absolute;
top: -0.25rem;
right: -0.5rem;
border-radius: 50%;
}
.author {
margin-bottom: 0.25rem;
}
.job {
margin-bottom: 0.5rem;
text-transform: uppercase;
color: var(--clr-primary-5);
font-size: 0.85rem;
}
.info {
margin-bottom: 0.75rem;
}
.prev-btn,
.next-btn {
color: var(--clr-primary-7);
font-size: 1.25rem;
background: transparent;
border-color: transparent;
margin: 0 0.5rem;
transition: var(--transition);
cursor: pointer;
}
.prev-btn:hover,
.next-btn:hover {
color: var(--clr-primary-5);
}
.random-btn {
margin-top: 0.5rem;
background: var(--clr-primary-10);
color: var(--clr-primary-5);
padding: 0.25rem 0.5rem;
text-transform: capitalize;
border-radius: var(--radius);
transition: var(--transition);
border-color: transparent;
cursor: pointer;
}
.random-btn:hover {
background: var(--clr-primary-5);
color: var(--clr-primary-1);
}
/*
src/index.css
*/
六、设计 Review 组件
接下来我们来完成本案例的核心 Review 组件,新建 Review.js 文件,用来展示卡片信息,设计思路如下:
引入 react-icons 组件,方便我们引入各种图标,比如本案例的左右箭头按钮,安装命令如下 npm install react-icons --save
引入我们刚才定义的用户数据, import people from './data';
定义索引状态 index,用于标识当前卡片显示哪个用户信息,初始默认为数组对象的第一个, const [index,setIndex]=useState(0);
接着分别定义用户信息状态的相关变量,用于展示用户的姓名、岗位、头像、介绍, const {name,job,image,text}=people[index];
我们继续定义按钮相关的事件,nextPerson(下一个),prevPerson(上一个),用于改变当前用户的索引状态,所以加1或减1 为了让用户卡片信息循环显示,比如触发 prevPerson 事件时,索引状态为负值时,让索引的状态为数组索引的最后一项;同样触发 nextPerson 事件时 ,索引状态大于数组的长度时,需要更改为数组索引的第一项,这里我们定义 checkNumber 方法用于判断索引的状态,更改索引状态的值 最后我们来定义 randomPerson 事件,用于随机显示用户的信息,这里需要注意处理如果随机的索引恰好等于当前用户的索引,避免用户误以为程序点了没反应,我们需要通过索引+1的方式进行更改。
思路就聊到这里,完整的代码如下所示:
import React, { useState } from 'react';
import people from './data';
import { FaChevronLeft, FaChevronRight, FaQuoteRight } from 'react-icons/fa';
const Review = () => {
const [index,setIndex]=useState(0);
const {name,job,image,text}=people[index];
const checkNumber = (number)=>{
if(number>people.length-1){
return 0;
}
if(number<0){
return people.length-1;
}
return number;
};
const nextPerson = ()=>{
setIndex((index)=>{
let newIndex= index + 1;
return checkNumber(newIndex);
});
};
const prevPerson =()=>{
setIndex((index)=>{
let newIndex=index-1;
return checkNumber(newIndex);
});
};
const randomPerson=()=>{
let randomNumber=Math.floor(Math.random()*people.length);
if(randomNumber===index){
randomNumber=index+1;
}
setIndex(checkNumber(randomNumber));
};
return (
<article className='review'>
<div className='img-container'>
<img src={image} alt={name} className='person-img'/>
<span className='quote-icon'>
< FaQuoteRight/>
</span>
</div>
<h4 className='author'>{name}</h4>
<p className='job'>{job}</p>
<p className='info'>{text}</p>
<div className='button-container'>
<button className='prev-btn' onClick={prevPerson}>
<FaChevronLeft/>
</button>
<button className='next-btn' onClick={nextPerson}>
<FaChevronRight/>
</button>
</div>
<button className="random-btn" onClick={randomPerson}>
surprise me
</button>
</article>
);
};
export default Review;
// src/Review.js
七、结束语
到这里,本案例就完成了,是不是很简单,点击卡片切换信息的比较常见,建议大家亲自动手练习下,大家可以点击阅读原文,在线体验,如果你想获取本案例源码,请关注“前端达人”公众号,回复“b2”。感谢你的阅读。