挑战用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
相关推荐
码农老起几秒前
掌握 React:组件化开发与性能优化的实战指南
react.js·前端框架
鸿蒙自习室几秒前
鸿蒙UI开发——组件滤镜效果
开发语言·前端·javascript
m0_748250748 分钟前
高性能Web网关:OpenResty 基础讲解
前端·openresty
前端没钱34 分钟前
从 Vue 迈向 React:平滑过渡与关键注意点全解析
前端·vue.js·react.js
NoneCoder38 分钟前
CSS系列(29)-- Scroll Snap详解
前端·css
无言非影42 分钟前
vtie项目中使用到了TailwindCSS,如何打包成一个单独的CSS文件(优化、压缩)
前端·css
我曾经是个程序员1 小时前
鸿蒙学习记录
开发语言·前端·javascript
羊小猪~~1 小时前
前端入门之VUE--ajax、vuex、router,最后的前端总结
前端·javascript·css·vue.js·vscode·ajax·html5
Hejjon1 小时前
SpringBoot 整合 SQLite 数据库
笔记
摸鱼了2 小时前
🚀 从零开始搭建 Vue 3+Vite+TypeScript+Pinia+Vue Router+SCSS+StyleLint+CommitLint+...项目
前端·vue.js