挑战用React封装100个组件【006】
项目地址
https://github.com/hismeyy/react-component-100
组件描述
组件适用于展示个人信息,别人还可以关注,发消息操作
样式展示
前置依赖
今天我们的这个挑战需要用用到了 react-icons
依赖,因此,我们需要先安装它。
# 使用 npm
npm install react-icons
# 或者使用 yarn
yarn add react-icons
使用的话,大家可以看这个网站。大家进去可以找需要的图标。具体使用里面有介绍,非常简单。
react-icons 图标
好了,下面我们展示代码。(如果对你有用,记得点个收藏或者关注哦!)
代码展示
InfoCard.tsx
import './InfoCard.css'
import { FaStar } from 'react-icons/fa';
interface InfoCardProps {
avatarUrl: string;
avatarAlt: string;
name: string;
description: string;
labels: string[];
isVerified?: boolean;
onFollow?: () => void;
onMessage?: () => void;
}
const InfoCard = ({
avatarUrl,
avatarAlt,
name,
description,
labels,
isVerified = false,
onFollow,
onMessage
}: InfoCardProps) => {
const displayLabels = labels.slice(0, 6);
return (
<div className='info-card'>
<div className="info">
<div className='info-avatar'>
<div className='tip-logo'>
{isVerified ? <FaStar /> : null}
</div>
<div className='avatar'>
<img src={avatarUrl} alt={avatarAlt} />
</div>
</div>
<div className='about-me'>
<h6>{name}</h6>
<p>{description}</p>
</div>
</div>
<div className='labels'>
{displayLabels.map((label, index) => (
<div key={index} className='label'>{label}</div>
))}
</div>
<div className='buttons'>
<button onClick={onFollow}>关注</button>
<button onClick={onMessage}>发消息</button>
</div>
</div>
)
}
export default InfoCard
InfoCard.css
.info-card {
box-sizing: border-box;
width: 430px;
height: 200px;
border-radius: 25px;
padding: 25px;
background-color: #F5F5F5;
border: 1px solid #b9b9b9;
display: flex;
justify-content: left;
flex-direction: column;
}
.info-card .info {
display: flex;
}
.info-card .info .info-avatar {
height: 60px;
position: relative;
}
.info-card .info .info-avatar .avatar {
width: 60px;
height: 60px;
border-radius: 50%;
overflow: hidden;
border: 1px solid #b9b9b9;
}
.info-card .info .info-avatar .avatar img {
width: 100%;
height: 100%;
object-fit: cover;
}
.info-card .info .info-avatar .tip-logo {
position: absolute;
bottom: 2px;
right: -4px;
width: 20px;
height: 20px;
background-color: #FA7D73;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
color: #fff;
font-size: 14px;
z-index: 1;
}
.info-card .info .about-me {
margin-left: 20px;
height: 60px;
display: flex;
flex-direction: column;
justify-content: center;
gap: 10px;
}
.info-card .info .about-me h6 {
all: unset;
display: block;
font-size: 16px;
font-weight: bold;
}
.info-card .info .about-me p {
all: unset;
display: block;
color: #696969;
font-size: 14px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 300px;
}
.info-card .labels {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 20px;
font-size: 10px;
color: #5c5c5c;
}
.info-card .labels .label {
background-color: #e2e2e2;
padding: 2px 5px;
border-radius: 20px;
cursor: pointer;
}
.info-card .buttons {
margin-top: 20px;
display: flex;
justify-content: center;
gap: 20px;
}
.info-card .buttons button {
all: unset;
padding: 5px 10px;
border-radius: 20px;
cursor: pointer;
font-size: 12px;
width: 50px;
height: 20px;
display: flex;
justify-content: center;
align-items: center;
transition: transform 0.2s ease, opacity 0.2s ease;
}
.info-card .buttons button:hover {
transform: translateY(-2px);
opacity: 0.8;
}
.info-card .buttons button:first-child {
background-color: #FA7D73;
color: #fff;
}
.info-card .buttons button:last-child {
background-color: rgb(101, 124, 224);
color: #fff;
}
使用
App.tsx
import './App.css'
import InfoCard from './components/card/infoCard04/InfoCard';
function App() {
const handleFollow = () => {
console.log('关注成功');
};
const handleMessage = () => {
console.log('打开消息框');
};
return (
<>
<div className="App">
<InfoCard
avatarUrl="https://p7.itc.cn/q_70/images03/20230309/bc24a67a4dea4ae38296967a4f8ecea5.png"
avatarAlt="MaxCosmos Avatar"
name="MaxCosmos"
description="前端开发工程师 | React开发者 | 热衷于打造优秀的用户体验和高性能web应用"
labels={["React", "Next.js", "TypeScript", "UI/UX", "Tailwind", "Node.js"]}
isVerified={true}
onFollow={handleFollow}
onMessage={handleMessage}
/>
</div>
</>
);
}
export default App