挑战用React封装100个组件【003】

项目地址
https://github.com/hismeyy/react-component-100

组件描述

组件适用于展示个人信息

样式展示

前置依赖

今天我们的这个挑战需要用用到了 react-icons 依赖,因此,我们需要先安装它。

cmd 复制代码
# 使用 npm
npm install react-icons

# 或者使用 yarn
yarn add react-icons

使用的话,大家可以看这个网站。大家进去可以找需要的图标。具体使用里面有介绍,非常简单。
react-icons 图标

好了,下面我们展示代码。

代码展示

InfoCard.tsx
js 复制代码
import './InfoCard.css'
import { BsFillCheckCircleFill } from "react-icons/bs";
import { BsPersonHearts } from "react-icons/bs";
import { BsTrophyFill } from "react-icons/bs";
import { FaStar } from 'react-icons/fa';

interface InfoCardProps {
    title?: string;
    avatarUrl?: string;
    name?: string;
    job?: string;
    progress?: number;
    likes?: number;
    checks?: number;
    trophies?: number;
}

const defaultProps: InfoCardProps = {
    title: "个人中心",
    avatarUrl: "https://images.unsplash.com/photo-1633332755192-727a05c4013d?w=500&h=500&q=80",
    name: "MaxCosmos",
    job: "React 开发工程师",
    progress: 85,
    likes: 128,
    checks: 46,
    trophies: 15
}

const InfoCard = (props: InfoCardProps) => {
    const {
        title,
        avatarUrl,
        name,
        job,
        progress = defaultProps.progress,
        likes,
        checks,
        trophies
    } = { ...defaultProps, ...props };

    const circumference = 2 * Math.PI * 60;
    const strokeDashoffset = circumference - ((progress || 0) / 100) * circumference;

    return (
        <div className='info-card'>
            <div className='info-title'>
                <h6>{title}</h6>
            </div>
            <div className='info-avatar'>
                <div className='tip-logo'>
                    <FaStar />
                </div>

                <svg className='avatar-bg' width="130" height="130" viewBox="0 0 130 130" xmlns="http://www.w3.org/2000/svg">
                    <circle cx="65" cy="65" r="60" stroke="#E0E1E6" stroke-width="5" fill="none" />
                    <circle cx="65" cy="65" r="60" stroke="#FA7D73" stroke-width="5" fill="none"
                        stroke-dasharray={circumference} stroke-dashoffset={strokeDashoffset} stroke-linecap="round" />
                </svg>

                <div className='avatar'>
                    <img src={avatarUrl} alt={name} />
                </div>
            </div>
            <div className="info">
                <p className='info-name'>{name}</p>
                <p className='info-job'>{job}</p>
            </div>

            <div className='info-other'>
                <div><BsPersonHearts style={{ color: '#FF451C' }} />&nbsp;&nbsp;{likes}</div>
                <div><BsFillCheckCircleFill style={{ color: '#FF451C' }} />&nbsp;&nbsp;{checks}</div>
                <div><BsTrophyFill style={{ color: '#FF451C' }} />&nbsp;&nbsp;{trophies}</div>
            </div>
        </div>
    )
}

export default InfoCard
InfoCard.css
js 复制代码
.info-card {
    box-sizing: border-box;
    width: 320px;
    height: 400px;
    border-radius: 25px;
    background-color: #FFFFFF;
    box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.0.1);
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 30px;
    overflow: hidden;
    font-family: "Microsoft YaHei", SimSun, "PingFang SC", "Helvetica Neue", Arial, sans-serif;
}

.info-card .info-title {
    width: 100%;
    display: flex;
    justify-content: left;
}

.info-card .info-title h6{
    all: unset;
    font-weight: bold;
    letter-spacing: 2px;
}

.info-card .info-avatar{
    margin-top: 20px;
    background-color: #FFFFFF;
    width: 130px;
    height: 130px;
    overflow: hidden;
    display: flex;
    justify-content: center;
    align-items: center;
    position:relative;
    
}

.info-card .info-avatar .tip-logo{
    position: absolute;
    width: 25px;
    height: 25px;
    bottom: 10px;
    right: 10px;
    border-radius: 50%;
    background-color: black;
    z-index: 5;
    display: flex;
    justify-content: center;
    align-items: center;
    color: #FFFFFF;
    font-size: 14px;
}

.info-card .info-avatar .avatar-bg{
    position: absolute;
    top: 0;
    left: 0;
    transform: rotate(-90deg);
}


.info-card .info-avatar .avatar{
    width: 90px;
    height: 90px;
    border-radius: 100%;
}



.info-card .info-avatar .avatar img{
    all: unset;
    width: 100%;
    height: 100%;
    background-color: #FA7D73;
    border-radius: 100%;
    overflow: hidden;
}

.info-card .info {
    margin-top: 20px;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center
}

.info-card .info .info-name{
    all: unset;
    font-weight: bold;
    font-size: 20px;
}

.info-card .info .info-job{
    all: unset;
    font-size: 14px;
    color: #B3B3B3;
    margin-top: 10px;
    font-weight: bold;
}

.info-card .info-other{
    display: flex;
    justify-content: space-around;
    width: 100%;
    margin-top: 40px;
}

.info-card .info-other div{
    width: 70px;
    height: 35px;
    display: flex;
    justify-content: center;
    align-items: center;
    border-radius: 17.5px;
    box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.1);
    font-size: 13px;
    font-weight: bold;
}

使用

App.tsx
js 复制代码
import './App.css'
import InfoCard from './components/card/infoCard03/InfoCard'

function App() {
  return (
    <>
      <InfoCard />
    </>
  )
}

export default App
相关推荐
IT_陈寒19 分钟前
Python 3.12 新特性实战:5个让你的代码效率提升50%的技巧!🔥
前端·人工智能·后端
Apifox20 分钟前
Apifox 8 月更新|新增测试用例、支持自定义请求示例代码、提升导入/导出 OpenAPI/Swagger 数据的兼容性
前端·后端·测试
我们从未走散24 分钟前
设计模式学习笔记-----抽象责任链模式
java·笔记·学习·设计模式·责任链模式
coding随想28 分钟前
最后的挽留:深入浅出HTML5 beforeunload事件
前端
Magnetic_h39 分钟前
【iOS】内存管理及部分Runtime复习
笔记·学习·macos·ios·objective-c·cocoa·xcode
亚里士多德芙40 分钟前
记录:离线包实现桥接
前端
车前端1 小时前
React 18 核心新特性解析
react.js
去伪存真1 小时前
用的好好的vue.config.js代理,突然报308, 怎么回事?🤔
前端
搞个锤子哟1 小时前
el-select使用filter-method实现自定义过滤
前端
flyliu1 小时前
什么是单点登录,如何实现
前端