如何使用 React 和 Tailwind CSS 构建作品集网站
每个开发人员都必须有一个作品集网站来展示他们的技能和项目。
如果您更喜欢视频教程,可以在这里观看:
在本文中,我将向您展示如何做到这一点。
我们将使用 React.js 和 Tailwind CSS 构建作品集网站。
你可能会问,这只是一个登陆页面?
为什么不直接用原生 CSS 和 HTML 来构建呢?
我选择 React 和 Tailwind 来构建这个项目是因为我会将博客 API 集成到这个项目中。我会在以后的文章中分享。
先决条件:
为了跟上进度,您不需要成为任何方面的专家,您所需要的只是基础知识。
- 对 vanilla CSS 有基本的了解
- 对 JavaScript 有基本的了解。
- React 和 Tailwind 的基础知识。
现在您知道您需要什么了,让我们开始构建吧。
设置
要构建项目,首先我们需要设置一个 React.js 和 Tailwind CSS 项目。你可以使用 Tailwind 文档轻松完成此操作。
请按照Tailwind 文档中的说明设置项目。
我会等你设置好项目。
您已完成!
让我们继续下一步。
组件
在开始之前,我们需要了解一些有关项目结构的知识。
因为它是 React,所以我们会将网站分解成微小的组件。
我们将有 6 个组成部分:
- 标题
- 英雄
- 关于
- 项目
- 博客
- 页脚
注意:所有这些组件都位于src文件夹下的 components 文件夹中。所有组件都将导入到App.js文件中。
像这样:
import "./App.css";
import Header from "./components/Header";
import Hero from "./components/Hero";
import About from "./components/About";
import Projects from "./components/Projects";
import Blog from "./components/Blog";
import Contact from "./components/Contact";
import Footer from "./components/Footer";
function App() {
return (
<>
<Header />
<Hero />
<About />
<Projects />
<Blog />
<Contact />
<Footer />
</>
);
}
export default App;
#1. 标题
它们有一个带有切换按钮的响应式移动菜单和一个桌面菜单。
我们将使用 React 的 useState hook 来实现切换效果。对于图标,我们将使用 React Icons 库。
import React, { useState } from "react";
import { AiOutlineMenu, AiOutlineClose } from "react-icons/ai";
const Header = () => {
const [toggle, setToggle] = useState(false);
const handleToggle = () => setToggle(!toggle);
return (
<header className="flex justify-between px-5 py-2 bg-primary text-white fixed w-full z-10">
<a href="/" className="logo text-2xl font-bold text-accent">
Amrin
</a>
{/* Desktop Nav */}
<nav className="hidden md:block">
<ul className="flex">
<li>
<a href="/#about">About</a>
</li>
<li>
<a href="/#projects">Projects</a>
</li>
<li>
<a href="/#blog">Blog</a>
</li>
<li>
<a href="/#contact">Contact</a>
</li>
<li>
<a href="#resume -link" target="_blank" without rel="noreferrer">
Resume
</a>
</li>
</ul>
</nav>
{/* Mobile Nav */}
<nav
className={!toggle ? "mobile-nav left-[-100%]" : "mobile-nav left-0"}
>
<ul className="flex flex-col">
<li>
<a href="/#about">About</a>
</li>
<li>
<a href="/#projects">Projects</a>
</li>
<li>
<a href="/#blog">Blog</a>
</li>
<li>
<a href="/#contact">Contact</a>
</li>
<li>
<a href="/#resume">Resume</a>
</li>
</ul>
</nav>
{/* Toggle button */}
<button onClick={handleToggle} className="block md:hidden">
{!toggle ? <AiOutlineMenu size={30} /> : <AiOutlineClose size={30} />}
</button>
</header>
);
};
export default Header;
因为我们有一个自定义调色板,所以我决定为颜色创建一些实用程序类。
/* color */
.bg-primary {
background: #0F172A;
}
.bg-secondery {
background: #1E293B;
}
.bg-accent {
background: #7477FF;
}
.text-accent {
color: #7477FF;
}
当我们用 Tailwind 为移动端导航设计样式时,它变得非常混乱和重复。因此,我决定提取这些类,并将它们放在 Style.css 文件中名为 .mobile-nav 的自定义类中,如下所示
.mobile-nav {
@apply block md:hidden fixed top-10 py-2 w-full h-full bg-gray-900 duration-500;
}
另外,为了给导航栏中的 a 标签添加样式,我们使用了一些自定义 CSS。否则我们会重复很多工作。
nav li a {
@apply px-4 py-5 text-lg;
}
nav li a:hover {
color: #7477FF;
}
现在我们已经完成了导航,让我们继续进入英雄部分。
#2. 英雄
英雄由两部分组成,一部分是英雄信息,另一部分是英雄图片。
我在英雄图像上使用了插图,如果您愿意,您可以使用您的图片。
import React from "react";
import HeroImg from "../assets/hero-img.png";
import {
AiOutlineTwitter,
AiOutlineYoutube,
AiOutlineFacebook,
} from "react-icons/ai";
const Hero = () => {
return (
<section className="bg-primary px-5 text-white py-32">
<div className="container mx-auto grid md:grid-cols-2 items-center justify-center md:justify-between">
<div className="hero-info pb-5 md:pb-0">
<h1 className="text-4xl lg:text-6xl">
Hi, <br />I am <span className="text-accent">a</span>mrin <br />
Frontend Developer
</h1>
<p className="py-5">
I am proficient in JavaScript, React.js and Tailwind CSS
</p>
<div className="flex py-5 ">
<a
href="https://twitter.com/CoderAmrin"
className="pr-4 inline-block text-accent hover:text-white"
>
{" "}
<AiOutlineTwitter size={40} />{" "}
</a>
<a
href="https://www.youtube.com/@coderamrin"
className="pr-4 inline-block text-accent hover:text-white"
>
{" "}
<AiOutlineYoutube size={40} />{" "}
</a>
<a
href="https://www.facebook.com/CoderAmrin/"
className="pr-4 inline-block text-accent hover:text-white"
>
{" "}
<AiOutlineFacebook size={40} />{" "}
</a>
</div>
<a
href="/#projects"
className=" btn bg-accent border-2 border-[#7477FF] text-white px-6 py-3 hover:bg-transparent"
>
See Projects
</a>
</div>
<div className="hero-img">
<img
src={HeroImg}
alt="coding illustration"
className="lgw-[80%] ml-auto"
/>
</div>
</div>
</section>
);
};
export default Hero;
为了设计英雄标题的风格,我们使用了自定义字体并添加了一些自定义样式。
注意:您需要在项目的 index.html 中添加此字体。这是一款免费的 Google 字体。
/* hero */
h1 {
font-family: 'Pacifico', cursive;
line-height: 1.5 !important;
}
#3. 关于
关于部分与英雄部分一样,由两部分组成。
第一部分会介绍你的所有信息,包括你的技能以及你的工作内容。另一部分是 about-img,它是一个关于一个人编程的插图。
注意:所有图像都位于 src/assets 目录中。
import React from "react";
import AboutImg from "../assets/about-img.png";
const About = () => {
return (
<section className="bg-secondery text-white px-5 py-32" id="about">
<div className="container mx-auto grid md:grid-cols-2 items-center justify-center md:justify-between">
<div className="about-info">
<h2 className="text-4xl font-bold mb-5 border-b-[5px] w-[180px] border-indigo-600 pb-2">
About Me
</h2>
<p className="pb-5">
Hi, My Name Is Rohima Akther everyone calls me Amrin. I am a
Frontend Developer. I build beautifull websites with React and
Tailwind CSS.
</p>
<p className="pb-5">
I am proficient in Frontend skills like React.js, Redux, Redux Tool
Kit, Axios, Tailwind CSS, SaSS, Css3 and many more.
</p>
<p>In backend I know Node.js, Express.js, MongoDB, and Mongoose</p>
<p>
In my spare time I create YouTube videos and write blogs on my Blog.
Where I talk about programming theory and build various projects.
</p>
</div>
<div className="about-img">
<img
src={AboutImg}
alt="coding illustration"
className="lgw-[80%] md:ml-auto"
/>
</div>
</div>
</section>
);
};
export default About;
为了设计此部分,除了颜色类之外,我们没有使用任何其他自定义 CSS。
#4. 项目
项目部分有点复杂。首先,我们将所有项目放在一个数组中,这样就不用重复操作了。有了这个项目数组,我们现在可以轻松地映射并渲染项目项。
const projects = [
{
img: devlog,
title: "devlog",
desc: " A multi author blog. Built with Node.js, MongoDB, React, Redux and Tailwind CSS ",
live: "https://devlogg.onrender.com/",
code: "https://github.com/Coderamrin/devlog",
},
{
img: uilogs,
title: "uilogs",
desc: "Free website template directory for SaaS and Degital Agency. Built with Bootstrap, JQuery and JavaScript",
live: "https://uilogs.xyz/",
code: "https://github.com/Coderamrin/html-templates",
},
{
img: cssProjects,
title: "css projects",
desc: "Frontend Mentor challange directory, solved with vanilla CSS",
live: "https://build-10-css-projects.netlify.app/",
code: "https://github.com/Coderamrin/build-10-css-projects",
},
{
img: getInspirred,
title: "get Inspirred",
desc: "Quote search app. Used Quotable API for the quotes and React, Redux on the frontend",
live: "https://get-inspirred.netlify.app/",
code: "https://github.com/Coderamrin/get-inspired",
},
];
产品组件的其余部分就是这样。
import React from "react";
import cssProjects from "../assets/cssprojects.png";
import devlog from "../assets/devlog.png";
import getInspirred from "../assets/get-inspirred.png";
import uilogs from "../assets/uilogs.png";
const Projects = () => {
const projects = [...];
return (
<section className="bg-primary text-white px-5 py-32" id="projects">
<div className="container mx-auto grid md:grid-cols-2 items-center md:justify-between">
<div className="about-info mb-5">
<h2 className="text-4xl font-bold mb-5 border-b-[5px] w-[180px] border-indigo-600 pb-2">
Projects
</h2>
<p className="pb-5">
These are some of my best projects. I have built these with React,
MERN and vanilla CSS. Check them out.
</p>
</div>
<div className="about-img"></div>
</div>
<div className="projects container mx-auto grid md:grid-cols-3 gap-10">
{projects.map((project, i) => {
return (
<div className="relative" key={i}>
<img src={project.img} alt={project.title} />
<div className="flex absolute left-0 right-0 top-[13px] bottom-0 mx-auto w-[90%] h-[90%] bg-primary opacity-0 duration-500 justify-center flex-col hover:opacity-100 ">
<p className="py-5 text-center font-bold px-2 text-white">
{project.desc}
</p>
<div className="mx-auto">
<a
href={project.live}
className="px-5 py-2 bg-blue-500 hover:bg-blue-600 mr-5 font-bold"
>
Live
</a>
<a
href={project.code}
className="px-5 py-2 bg-blue-700 hover:bg-blue-800 font-bold"
>
Code
</a>
</div>
</div>
</div>
);
})}
</div>
</section>
);
};
export default Projects;
#5. 博客
现在是博客部分。它几乎和项目部分一样。
要映射并呈现项目的博客项目数组。
其余一切都与项目组件相同。
import React from "react";
const Blog = () => {
const post = [
{
img: "https://res.cloudinary.com/practicaldev/image/fetch/s--AuZFJnr6--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a8okx5rxzuh5fojibsy3.png",
title: "How to build a counter app with JavaScript",
url: "https://dev.to/coderamrin/how-to-build-a-counter-app-with-javascript-439p",
},
{
img: "https://res.cloudinary.com/practicaldev/image/fetch/s--FsJZ6lhI--/c_imagga_scale,f_auto,fl_progressive,h_420,q_auto,w_1000/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gv7y2de8kalk9l0820ag.jpg",
title: "JavaScript Ultimate Guide 02: The DOM",
url: "https://dev.to/coderamrin/javascript-ultimate-guide-02-the-dom-3ho9",
},
];
return (
<section className="bg-primary text-white px-5 py-32" id="blog">
<div className="container mx-auto grid md:grid-cols-2 items-center md:justify-between">
<div className="about-info mb-5">
<h2 className="text-4xl font-bold mb-5 border-b-[5px] w-[100px] border-indigo-600 pb-2">
Blogs
</h2>
<p className="pb-5">Some of my best blogs.</p>
</div>
<div></div>
</div>
<div className="projects container mx-auto grid md:grid-cols-2 gap-10">
{post.map((item) => {
return (
<div>
<img src={item.img} alt={item.title} />
<h3 className="py-5 text-2xl">{item.title}</h3>
<a
href={item.url}
className=" btn bg-accent border-2 border-[#7477FF] text-white px-6 py-3 hover:bg-transparent"
>
Read More
</a>
</div>
);
})}
</div>
</section>
);
};
export default Blog;
#6. 联系方式和页脚
最后是联系部分和页脚部分。
这些部分只是 div 中心的一些文本。没什么特别的设计。
#接触
import React from "react";
const Contact = () => {
return (
<section className="bg-secondery px-5 py-32" id="contact">
<div className="text-center md:w-[60%] mx-auto text-white">
<h2 className="text-4xl font-bold mb-5 border-b-[5px] w-[200px] mx-auto border-indigo-600 pb-2">
Contact Me
</h2>
<p>
I am currently open for a fulltime Frontend Developer role. If you
want to discuss about that feel free to email me or call me.
</p>
<p className="py-2">
<span className="font-bold">Email:</span> coderamrin@gmail.com
</p>
<p className="py-2">
<span className="font-bold">Phone:</span> +88 01624-890723
</p>
</div>
</section>
);
};
export default Contact;
#页脚
import React from "react";
const Footer = () => {
return <div className="py-4 text-center bg-primary text-white "> © 2023 coderamrin all right reserved</div>;
};
export default Footer;
资源
直播: https://amrin.onrender.com/
源代码: https://github.com/Coderamrin/portfolio
结论
现在您有了一个作品集。您可以部署它并展示您的项目。
如果您愿意,您可以将博客添加到您的作品集并展示您的技能。
我将在这个作品集上添加 dev api,如果您想看到同样的事情,请关注我,以便在我发布文章时收到通知。
如果您想与我联系,您可以在Twitter和YouTube上找到我。
感谢您阅读到最后。
我们下篇文章再见。
文章来源:https://dev.to/coderamrin/how-to-build-a-portfolio-website-with-react-tailwind-css-fni