38 分钟
AI 时代的全栈 App 开发实战

UI 组件库与状态管理:把界面做漂亮、把状态管清楚

就练这几块:主流UI组件库怎么选,怎么搭设计系统,Tailwind CSS怎么用,Zustand/Redux/Jotai/Context这几个状态管理方案怎么比、怎么选,还有别踩状态管理的坑

  • 理解 UI 组件库的价值和选型维度,了解 React/Vue 生态的主流组件库
  • 掌握 Tailwind CSS 实用优先的核心理念,知道什么时候不用它
  • 理解设计系统(Design System)的构成:色彩、字体、间距、组件、文档
  • 掌握前端状态管理的核心概念和主流方案对比(Zustand/Redux/Jotai/Context)
  • 选状态管理方案就看应用规模和复杂度,别搞过度工程,也避开常见坑

UI 组件库:站在巨人肩膀上

从零写每一个按钮、输入框、弹窗、表格,是浪费生命。UI组件库就是别人已经写好、测试好、设计好的通用组件集合,你拿来用,把时间花在产品特有的业务逻辑上。选型维度:设计风格(Material Design/蚂蚁设计/极简/拟物);组件丰富度(有没有你需要的表格、树形、富文本、上传);定制难度(能不能改样式、改主题、改行为);TypeScript支持;维护活跃度;包体积和按需加载。

示例代码(可运行)
🐍UI 组件库选型心法

后台管理/SaaS → Ant Design Pro(开箱即用,表格/表单/权限/图表全有),这是最稳妥的选择,不要自己造轮子;面向 C 端用户的产品(App/官网/落地页)→ 不要用 Ant Design(企业感太重),用 shadcn/ui + Tailwind(极简、可定制、设计感强)或 Chakra UI;有设计团队、要完全自定义外观 → Radix UI(只管行为和无障碍,样式自己写);快速原型/MVP → Tailwind CSS + shadcn/ui,最快出效果;不要混用多个组件库(Ant Design + MUI + 自定义混在一起,样式冲突、包体积大、维护混乱),选一个主力,不够的自己写。

Tailwind CSS:实用优先的 CSS 革命

传统写 CSS 的方式:HTML 里写 class 名,再在 CSS 文件里写这个 class 的样式。问题是:得不断想 class 命名,还要在 HTML 和 CSS 文件之间来回切,样式写多了最后不敢删,怕影响别的地方。 Tailwind 的思路是:提供大量原子化 CSS 类,比如 flex、p-4、text-lg、bg-blue-500、hover:bg-blue-600,直接在 HTML 元素上写这些类,不用写自定义 CSS,不用想命名,不用切换文件。

Python
// Tailwind 示例:一个卡片按钮(样式全写在 class 里,不需要 CSS 文件)
// <button class="bg-blue-500 hover:bg-blue-600 text-white font-semibold py-2 px-4 rounded-lg shadow-md transition-colors">
//   点击我
// </button>

// 等价的传统 CSS:
// HTML: <button class="btn-primary">点击我</button>
// CSS:
// .btn-primary {
//   background-color: #3b82f6;
//   color: white;
//   font-weight: 600;
//   padding: 0.5rem 1rem;
//   border-radius: 0.5rem;
//   box-shadow: 0 4px 6px rgba(0,0,0,0.1);
//   transition: background-color 0.2s;
// }
// .btn-primary:hover { background-color: #2563eb; }
print("Tailwind: 样式写在 class 里,不用想命名,不用切文件,不用怕删")
ℹ️Tailwind 的优势

不用想 class 命名,不用在 HTML/CSS 间切换,样式直接写在元素上,开发速度快;看 HTML 就知道这个元素长什么样,不用跳转到 CSS 文件找,样式和元素在一起;Tailwind JIT 只打包用到的类,用不到的类不会被打包,不会有「死代码」,包体积可控;间距(p-1/p-2/p-4)、颜色(blue-500/blue-600)、字号(text-sm/text-lg)都是预设的设计令牌,天然保持一致性,设计系统内置;shadcn/ui、Headless UI 等都基于 Tailwind,生态繁荣;AI 对 Tailwind 类名的理解和生成非常准确,因为训练数据多,AI 生成质量高。

⚠️Tailwind 的劣势和不适用场景

HTML变得很长:一个元素可能有10+个类,可读性下降,用@apply提取公共样式缓解;需要记住大量类名,有学习成本,但常用的就30个左右,用一周就熟了;不适合需要大量复杂动画/高级CSS的场景,复杂的keyframes、CSS变量、伪元素还是要写自定义CSS;团队审美不一致时可能失控,每个人写的类名组合不同,需要设计规范约束;已经有成熟的设计系统和CSS架构,迁移到Tailwind成本不低。本课程的朋友好学 App 用的正是 Tailwind CSS(v4,在 globals.css 里用 @import 引入),再叠加全局设计令牌统一主题色、毛玻璃和间距,兼顾原子化的高效与全 App 的视觉一致。

选择题

以下哪个场景最适合用 Tailwind CSS?

设计系统:让产品看起来「专业」的秘密

为什么有些App看着山寨,有些看着高级?区别不是单个组件好不好看,是有没有统一的设计系统。设计系统是一套设计语言的规则和组件集合,包括:色彩系统(主色/辅助色/语义色/中性色,每个颜色有50-900的色阶);字体系统(字号阶梯/字重/行高/字间距);间距系统(4px基准,4/8/12/16/24/32/48);圆角/阴影/边框/动效规范;组件库(按钮/输入框/卡片/弹窗/表格,每个组件有多种状态:默认/hover/active/disabled/focus);设计文档(什么时候用什么组件、什么场景用什么颜色)。

💡一个人/小团队怎么建设计系统

别从零设计。选成熟设计系统当基础:Tailwind 默认配色加 shadcn/ui 组件,或者 Ant Design 设计语言;定 3-5 个核心颜色:主色、成功色(绿)、警告色(黄)、错误色(红)、中性色(灰阶);用 4px 基准间距:所有 padding/margin/gap 都是 4 的倍数(4/8/12/16/20/24/32/40/48);字号用固定阶梯:12/14/16/18/20/24/30/36/48,别出 13px/15px/17px 这种野字号;圆角统一:小 4px/中 8px/大 12px/圆 9999px,别每个组件圆角都不一样;所有按钮/输入框/卡片用同一套组件,别这里一个样式那里一个样式。做到这几点,产品看起来就专业很多。

状态管理:前端最容易过度工程的地方

状态管理是前端开发里讨论最多、但最容易搞复杂的话题。新手一上来就想「我要用 Redux,因为它是企业级标准」,结果一个简单的表单应用写了一堆 action/reducer/saga,代码量翻三倍。状态管理的核心问题是:「哪些状态需要跨组件共享?」——如果状态只在一个组件里用,useState/useRef 就够了;如果要跨组件共享,再考虑用 Context 或状态管理库。

状态管理方案选型决策树(React 生态)状态只在一个组件里用? → useState / useRef(90% 的状态属于这一类!)状态要跨几个组件共享,且不复杂? → React Context + useReducer(不需要第三方库)状态要全局共享,中等复杂度,想要简单? → Zustand(API 极简,几行代码创建 store,本课程朋友好学 App 用的就是 Zustand)状态复杂,需要时间旅行调试/严格的单向数据流/大型团队? → Redux Toolkit(Redux 的现代写法,比原生 Redux 简单很多)追求细粒度响应式/极致性能,类 Solid 风格? → Jotai(原子化状态,细粒度更新)服务端状态(数据请求/缓存/分页)? → React Query / SWR(这不是「状态管理库」,是「服务端状态管理库」,不要混用)先问「需不需要跨组件共享」,再选方案,不要一上来就 Redux

Zustand:最简单的状态管理(朋友好学 App 的选择)

Zustand 是 React 生态里用得最多的轻量状态管理库,核心就是 API 极简,没什么样板代码。写几行代码就能创建一个 store,组件里直接用,不用 Provider,不用 reducer,不用 action type。朋友好学 App 的学习进度、AI 设置、聊天历史、主题切换,都是用 Zustand 管的。

TypeScript
// Zustand 示例:一个用户状态 store(朋友好学 App 的风格)
// import { create } from 'zustand';
// import { persist } from 'zustand/middleware';
//
// interface UserState {
//   name: string;
//   level: number;
//   xp: number;
//   setName: (name: string) => void;
//   addXp: (amount: number) => void;
// }
//
// export const useUserStore = create<UserState>()(
//   persist(
//     (set) => ({
//       name: '学习者',
//       level: 1,
//       xp: 0,
//       setName: (name) => set({ name }),
//       addXp: (amount) => set((state) => {
//         const newXp = state.xp + amount;
//         const newLevel = Math.floor(newXp / 100) + 1;
//         return { xp: newXp, level: newLevel };
//       }),
//     }),
//     { name: 'pygood-user-store' } // localStorage 持久化 key
//   )
// );
//
// 组件里用:
// const { name, level, xp, addXp } = useUserStore();
// // 或者选择器(避免不必要的重新渲染):
// const xp = useUserStore((s) => s.xp);
print("Zustand: 几行代码创建 store,支持 persist 持久化,选择器优化渲染")

Redux / Redux Toolkit:大型应用的工业标准

Redux 是经典状态管理库,核心理念是单向数据流 + 不可变状态 + 纯函数 reducer。传统 Redux 样板代码多,有 action type/action creator/reducer/switch case,所以现在用 Redux Toolkit(RTK)——官方推荐的现代写法,用 createSlice 合并 action/reducer,用 createAsyncThunk 处理异步,用 RTK Query 处理服务端状态。适合:大型团队、复杂状态、需要时间旅行调试、需要严格的状态变更可追溯。

Jotai:原子化状态管理

Jotai 的核心理念是「原子(atom)」——把状态拆成最小的原子单元,组件订阅哪个原子就只在那个原子变化时重新渲染,不需要 useMemo 优化。API 类似 React 的 useState,还可以跨组件共享。适合追求极致性能、有大量独立状态单元、需要类 Solid 细粒度响应式的场景。

⚠️状态管理的五个常见陷阱

一上来就用 Redux:90% 的应用不需要 Redux,useState+Context+Zustand 就够了,用 Redux 只会增加样板代码;把所有状态都放全局:局部状态(表单输入、弹窗开关、hover 状态)应该用 useState,放全局只会增加复杂度和渲染;服务端状态用客户端状态管理:数据请求/缓存/分页应该用 React Query/SWR,不要用 Redux/Zustand 管,你会自己写一堆 loading/error/cache 逻辑,重复造轮子;不做选择器优化:在 Zustand/Redux 里直接 const state = useStore() 会导致任何状态变化都重新渲染,应该用选择器 const xp = useStore(s => s.xp) 只订阅需要的部分;状态更新要不可变:React 状态更新必须不可变,不能直接 state.xp += 1,要 set({xp: state.xp + 1}),否则不会触发重新渲染,这是新手最常见的 bug。

本节小结

UI 组件库选型:后台用 Ant Design Pro,C 端用 shadcn/ui+Tailwind,有设计团队用 Radix UI,快速原型用 Tailwind+shadcn。Tailwind CSS 是实用优先的原子化 CSS 框架,开发快、样式和元素在一起、无死代码,但 HTML 变长、有学习成本。设计系统是产品看起来专业的秘密:色彩/字体/间距/圆角/组件统一,一个人也能从 Tailwind+shadcn 起步。状态管理最容易过度工程:先问「需不需要跨组件共享」,局部用 useState,跨组件简单用 Context,全局中等用 Zustand(朋友好学的选择),大型复杂用 Redux Toolkit,细粒度性能用 Jotai,服务端状态用 React Query。避开五个陷阱:不要一上来 Redux、不要所有状态全局、不要用客户端状态管服务端、要用选择器、要不可变更新。下一节讲用 AI 写前端——Cursor/Copilot/v0 的正确用法。

资深工程师加餐

底层原理 · 大厂视角 · 工程经验,点卡片展开

纯网页包壳容易被应用商店以“最小功能不足”驳回,关键在于用原生能力补足 Web 做不到的部分:权限申请(麦克风/摄像头)、安全键盘与键盘高度、状态栏与安全区、文件与分享、版本更新、扫码等。让 Web 负责快速迭代的内容与 UI,原生负责系统能力与体验兜底,这种混合架构才是套壳 App 的合规且高体验形态。