深入解析 Brainwave 项目:学习使用 React 和 Tailwind 构建复杂界面
每当设计师带来现代 AI 服务的风格模拟图时,开发者们都会感到一阵轻微的紧张。霓虹渐变、复杂的背景网格、区块边界处的装饰十字、 Bento 布局以及视差效果。要将这些元素整齐地组装起来,同时不让代码变成一堆散乱的 Tailwind 类名,确实是一项挑战。
在 brainwave 仓库中,JavaScript Mastery 频道的作者 Adrian Hajdin 发布了一个虚构 AI 产品的完整落地页源代码。该项目使用 React、Vite 和 Tailwind CSS 构建。这是一个很好的示例,展示了当设计超出标准卡片和按钮时,如何组织样式和组件架构。
项目内部结构
该仓库是一个现成的前端单页网站。它包含了商业网站的典型模块:带有行动号召的主横幅区、功能卡片、交互式路线图、集成区域和定价方案。
该项目的主要价值不在于设计本身,而在于实现复杂视觉元素的方法。作者展示了如何在不引入重型组件库依赖的情况下,充分利用原生 Tailwind CSS 和纯 React。
有趣的技术方案
我审查了代码库,总结出四个对实际开发有用的技术。
1. 通过 Tailwind 插件实现字体架构
在大型 Tailwind 项目中,一个常见问题会出现:开发者们会在不同的标题之间复制冗长的类名链,如 font-semibold text-[2.5rem] leading-[3.25rem] md:text-[2.75rem]。这会让标记变得杂乱,并使重构变得复杂。
在 Brainwave 中,这个问题通过配置文件 tailwind.config.js 来处理。作者使用内置函数 plugin 为所有字体级别创建了自定义组件类:
plugins: [
plugin(function ({ addBase, addComponents, addUtilities }) {
addComponents({
".h1": {
"@apply font-semibold text-[2.5rem] leading-[3.25rem] md:text-[2.75rem] md:leading-[3.75rem] lg:text-[3.25rem] lg:leading-[4.0625rem] xl:text-[3.75rem] xl:leading-[4.5rem]":
{},
},
".h2": {
"@apply text-[1.75rem] leading-[2.5rem] md:text-[2rem] md:leading-[2.5rem] lg:text-[2.5rem] lg:leading-[3.5rem] xl:text-[3rem] xl:leading-tight":
{},
},
".body-1": {
"@apply text-[0.875rem] leading-[1.5rem] md:text-[1rem] md:leading-[1.75rem] lg:text-[1.25rem] lg:leading-8":
{},
},
".tagline": {
"@apply font-grotesk font-light text-xs tracking-tagline uppercase":
{},
},
});
}),
]
现在在 JSX 中你只需要写 <h1 className="h1">,样式就会自动连同响应式断点一起被引入。
2. 带引导线的通用区块包装器
项目设计使用页面两侧的细分割线以及区块交叉处的装饰十字。手动在每个组件内部构建这些标记会很麻烦。
项目中包含了一个专用的 Section.jsx 组件来处理所有装饰性几何元素:
import SectionSvg from "../../public/assets/svg/SectionSvg";
const Section = ({
className,
id,
crosses,
crossesOffset,
customPaddings,
children,
}) => (
<div
id={id}
className={`relative
${
customPaddings ||
`py-10 lg:py-16 xl:py-20 ${crosses ? "lg:py-32 xl:py-40" : ""}`
} ${className || ""}`}
>
{children}
<div className="hidden absolute top-0 left-5 w-0.25 h-full bg-stroke-1 pointer-events-none md:block lg:left-7.5 xl:left-10" />
<div className="hidden absolute top-0 right-5 w-0.25 h-full bg-stroke-1 pointer-events-none md:block lg:right-7.5 xl:right-10" />
{crosses && (
<>
<div
className={`hidden absolute top-0 left-7.5 right-7.5 h-0.25 bg-stroke-1 ${
crossesOffset && crossesOffset
} pointer-events-none lg:block xl:left-10 right-10`}
/>
<SectionSvg crossesOffset={crossesOffset} />
</>
)}
</div>
);
该组件隔离了渲染侧边引导线(w-0.25 h-full bg-stroke-1)和带有交叉处 SVG 图标的水平分割线的逻辑。其他区块只需包装在 <Section crosses> 中,保持结构清晰。
3. 路线图的 Bento 布局
路线图区块构建为一个非对称网格。偶数序号的卡片在中大型屏幕上使用 even:md:translate-y-[7rem] 类进行垂直偏移。
渐变边框使用了双层包装技术:外层容器获得渐变背景(bg-conic-gradient)和最小内边距 p-0.25,而内部块填充主深色主题色 bg-n-8。这创建了一个仅几分像素宽的干净发光边框,无需使用重型 CSS 滤镜。
4. 将内容提取到常量
所有文本、导航结构、定价和功能列表都被提取到 constants/index.js 文件中。组件本身不包含硬编码字符串——它们只处理数据映射。要将项目适配到实际服务中,你只需修改一个 JS 对象,无需触碰 JSX 标记。
如何在本地运行项目
你需要安装 Node.js 和 Git 来运行该项目。克隆仓库并安装依赖:
git clone https://github.com/adrianhajdin/brainwave.git
cd brainwave
npm install
npm run dev
Vite 本地服务器启动在 http://localhost:5173。
谁适合使用这个仓库
该项目没有后端、数据库集成或复杂的状态管理。它专门作为一个前端开发模板和学习资源。
在以下两种场景下值得探索这个仓库:
- 你想提升 Tailwind CSS 技能,并了解如何为非标准设计模拟图正确定制主题。
- 你需要为你的副项目或作品集准备一个现成的落地页框架,其中令人印象深刻的视觉呈现很重要。
代码干净,分成清晰的模块,易于拆分为独立的可复用组件。源代码链接:github.com/adrianhajdin/brainwave。
相关项目