frontend-development

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Frontend Development Guidelines

前端开发指南

Purpose

目的

Comprehensive guide for modern frontend development across React, Vue 3, Svelte 5, and Angular. Covers framework-specific patterns, common architectural principles, and cross-framework best practices.
这份指南全面覆盖React、Vue 3、Svelte 5和Angular的现代前端开发,包含各框架专属模式、通用架构原则以及跨框架最佳实践。

When to Use This Skill

何时使用本技能

  • Creating components or pages in React, Vue, Svelte, or Angular
  • Building new features with framework-specific patterns
  • Implementing state management (Pinia, Zustand, stores, signals)
  • Setting up routing (TanStack Router, Vue Router, SvelteKit, Angular Router)
  • Data fetching patterns (TanStack Query, composables, SvelteKit load functions)
  • Performance optimization across frameworks
  • Component composition and reusability
  • TypeScript integration and best practices
  • Choosing the right framework for a project
  • Migrating between frameworks

  • 在React、Vue、Svelte或Angular中创建组件或页面
  • 使用框架专属模式构建新功能
  • 实现状态管理(Pinia、Zustand、stores、signals)
  • 配置路由(TanStack Router、Vue Router、SvelteKit、Angular Router)
  • 数据获取模式(TanStack Query、组合式函数、SvelteKit加载函数)
  • 跨框架性能优化
  • 组件组合与复用
  • TypeScript集成与最佳实践
  • 为项目选择合适的框架
  • 框架间迁移

Framework Selection Guide

框架选型指南

Choose your framework based on project requirements:
FrameworkBest ForLearning CurvePerformanceEcosystem
ReactLarge apps, strong typing, enterpriseMediumGoodLargest
Vue 3Progressive adoption, approachableLowExcellentGrowing
Svelte 5Small/medium apps, native feelLowBestSmaller
AngularEnterprise, full-featuredSteepGoodComplete
Quick Decision:
  • Existing codebase? Use what's there or plan migration
  • Team experience? Leverage existing knowledge
  • Project size? Large → React/Angular, Medium → Vue/React, Small → Svelte/Vue
  • Performance critical? Svelte > Vue > React ≈ Angular
  • TypeScript required? All support it well (Angular best integrated)
  • Ecosystem needs? React > Vue > Angular > Svelte
See framework-specific sections below for detailed patterns.

根据项目需求选择框架:
框架最适用场景学习曲线性能生态系统
React大型应用、强类型、企业级项目中等良好最庞大
Vue 3渐进式采用、易上手优秀持续增长
Svelte 5中小型应用、原生体验最佳相对较小
Angular企业级、全功能陡峭良好完善
快速决策建议:
  • 已有代码库? 沿用现有框架或规划迁移
  • 团队经验? 利用现有技术积累
  • 项目规模? 大型→React/Angular,中型→Vue/React,小型→Svelte/Vue
  • 性能优先级高? Svelte > Vue > React ≈ Angular
  • 要求TypeScript? 所有框架均支持(Angular集成度最佳)
  • 需要丰富生态? React > Vue > Angular > Svelte
查看下文各框架专属章节获取详细模式说明。

Quick Framework Comparison

框架快速对比

FeatureReactVue 3Svelte 5Angular
ReactivityHooks (useState)ref/reactiveRunes ($state)Signals
ComponentsJSX/TSXSFC (.vue)SFC (.svelte)Decorators/Class
State MgmtZustand/ContextPiniaStoresServices
RoutingReact Router/TanStackVue RouterSvelteKitAngular Router
Data FetchingTanStack QueryComposables/VueQueryLoad functionsHttpClient/RxJS
StylingCSS-in-JS/ModulesScoped CSSScoped CSSComponent styles
Full-StackNext.jsNuxtSvelteKitUniversal/SSR
Bundle Size~40KB~32KB~3KB~60KB
CompilerRuntimeRuntimeCompile-timeAOT Compiler
Jump to:

特性ReactVue 3Svelte 5Angular
响应式Hooks (useState)ref/reactiveRunes ($state)Signals
组件格式JSX/TSXSFC (.vue)SFC (.svelte)装饰器/类
状态管理Zustand/ContextPiniaStores服务
路由React Router/TanStackVue RouterSvelteKitAngular Router
数据获取TanStack Query组合式函数/VueQuery加载函数HttpClient/RxJS
样式CSS-in-JS/模块作用域CSS作用域CSS组件样式
全栈框架Next.jsNuxtSvelteKitUniversal/SSR
包体积~40KB~32KB~3KB~60KB
编译器运行时运行时编译时AOT编译器
快速跳转:

React Development

React开发

New Component Checklist

新组件检查清单

Creating a component? Follow this checklist:
  • Use
    React.FC<Props>
    pattern with TypeScript
  • Lazy load if heavy component:
    React.lazy(() => import())
  • Wrap in
    <SuspenseLoader>
    for loading states
  • Use
    useSuspenseQuery
    for data fetching
  • Import aliases:
    @/
    ,
    ~types
    ,
    ~components
    ,
    ~features
  • Styles: Inline if <100 lines, separate file if >100 lines
  • Use
    useCallback
    for event handlers passed to children
  • Default export at bottom
  • No early returns with loading spinners
  • Use
    useMuiSnackbar
    for user notifications
创建组件时,请遵循以下检查清单:
  • 使用
    React.FC<Props>
    模式结合TypeScript
  • 若为重型组件则启用懒加载:
    React.lazy(() => import())
  • <SuspenseLoader>
    包裹以处理加载状态
  • 使用
    useSuspenseQuery
    进行数据获取
  • 使用导入别名:
    @/
    ~types
    ~components
    ~features
  • 样式:代码少于100行则内联,超过100行则单独文件
  • 传递给子组件的事件处理器使用
    useCallback
  • 在底部导出默认组件
  • 不要用提前返回的方式显示加载 spinner
  • 使用
    useMuiSnackbar
    实现用户通知

New Feature Checklist

新功能检查清单

Creating a feature? Set up this structure:
  • Create
    features/{feature-name}/
    directory
  • Create subdirectories:
    api/
    ,
    components/
    ,
    hooks/
    ,
    helpers/
    ,
    types/
  • Create API service file:
    api/{feature}Api.ts
  • Set up TypeScript types in
    types/
  • Create route in
    routes/{feature-name}/index.tsx
  • Lazy load feature components
  • Use Suspense boundaries
  • Export public API from feature
    index.ts

创建功能时,请按以下结构配置:
  • 创建
    features/{feature-name}/
    目录
  • 创建子目录:
    api/
    components/
    hooks/
    helpers/
    types/
  • 创建API服务文件:
    api/{feature}Api.ts
  • types/
    中配置TypeScript类型
  • routes/{feature-name}/index.tsx
    中创建路由
  • 懒加载功能组件
  • 使用Suspense边界
  • 从功能的
    index.ts
    导出公共API

Import Aliases Quick Reference

导入别名速查

AliasResolves ToExample
@/
src/
import { apiClient } from '@/lib/apiClient'
~types
src/types
import type { User } from '~types/user'
~components
src/components
import { SuspenseLoader } from '~components/SuspenseLoader'
~features
src/features
import { authApi } from '~features/auth'
Defined in: vite.config.ts lines 180-185

别名指向路径示例
@/
src/
import { apiClient } from '@/lib/apiClient'
~types
src/types
import type { User } from '~types/user'
~components
src/components
import { SuspenseLoader } from '~components/SuspenseLoader'
~features
src/features
import { authApi } from '~features/auth'
定义位置:vite.config.ts 第180-185行

Common Imports Cheatsheet

常用导入速查表

typescript
// React & Lazy Loading
import React, { useState, useCallback, useMemo } from 'react';
const Heavy = React.lazy(() => import('./Heavy'));

// MUI Components
import { Box, Paper, Typography, Button, Grid } from '@mui/material';
import type { SxProps, Theme } from '@mui/material';

// TanStack Query (Suspense)
import { useSuspenseQuery, useQueryClient } from '@tanstack/react-query';

// TanStack Router
import { createFileRoute } from '@tanstack/react-router';

// Project Components
import { SuspenseLoader } from '~components/SuspenseLoader';

// Hooks
import { useAuth } from '@/hooks/useAuth';
import { useMuiSnackbar } from '@/hooks/useMuiSnackbar';

// Types
import type { Post } from '~types/post';

typescript
// React & 懒加载
import React, { useState, useCallback, useMemo } from 'react';
const Heavy = React.lazy(() => import('./Heavy'));

// MUI组件
import { Box, Paper, Typography, Button, Grid } from '@mui/material';
import type { SxProps, Theme } from '@mui/material';

// TanStack Query (Suspense)
import { useSuspenseQuery, useQueryClient } from '@tanstack/react-query';

// TanStack Router
import { createFileRoute } from '@tanstack/react-router';

// 项目组件
import { SuspenseLoader } from '~components/SuspenseLoader';

// Hooks
import { useAuth } from '@/hooks/useAuth';
import { useMuiSnackbar } from '@/hooks/useMuiSnackbar';

// 类型
import type { Post } from '~types/post';

Topic Guides

主题指南

🎨 Component Patterns

🎨 组件模式

Modern React components use:
  • React.FC<Props>
    for type safety
  • React.lazy()
    for code splitting
  • SuspenseLoader
    for loading states
  • Named const + default export pattern
Key Concepts:
  • Lazy load heavy components (DataGrid, charts, editors)
  • Always wrap lazy components in Suspense
  • Use SuspenseLoader component (with fade animation)
  • Component structure: Props → Hooks → Handlers → Render → Export
📖 Complete Guide: resources/component-patterns.md

现代React组件采用:
  • React.FC<Props>
    确保类型安全
  • React.lazy()
    实现代码分割
  • SuspenseLoader
    处理加载状态
  • 命名常量+默认导出模式
核心概念:
  • 懒加载重型组件(DataGrid、图表、编辑器)
  • 懒加载组件必须用Suspense包裹
  • 使用SuspenseLoader组件(带淡入动画)
  • 组件结构:Props → Hooks → 处理器 → 渲染 → 导出
📖 完整指南:resources/component-patterns.md

📊 Data Fetching

📊 数据获取

PRIMARY PATTERN: useSuspenseQuery
  • Use with Suspense boundaries
  • Cache-first strategy (check grid cache before API)
  • Replaces
    isLoading
    checks
  • Type-safe with generics
API Service Layer:
  • Create
    features/{feature}/api/{feature}Api.ts
  • Use
    apiClient
    axios instance
  • Centralized methods per feature
  • Route format:
    /form/route
    (NOT
    /api/form/route
    )
📖 Complete Guide: resources/data-fetching.md

首选模式:useSuspenseQuery
  • 结合Suspense边界使用
  • 缓存优先策略(先检查网格缓存再调用API)
  • 替代
    isLoading
    检查
  • 泛型支持确保类型安全
API服务层:
  • 创建
    features/{feature}/api/{feature}Api.ts
  • 使用
    apiClient
    axios实例
  • 按功能集中管理方法
  • 路由格式:
    /form/route
    (而非
    /api/form/route
📖 完整指南:resources/data-fetching.md

📁 File Organization

📁 文件组织

features/ vs components/:
  • features/
    : Domain-specific (posts, comments, auth)
  • components/
    : Truly reusable (SuspenseLoader, CustomAppBar)
Feature Subdirectories:
features/
  my-feature/
    api/          # API service layer
    components/   # Feature components
    hooks/        # Custom hooks
    helpers/      # Utility functions
    types/        # TypeScript types
📖 Complete Guide: resources/file-organization.md

features/ vs components/:
  • features/
    :领域专属(帖子、评论、认证)
  • components/
    :通用可复用(SuspenseLoader、CustomAppBar)
功能子目录结构:
features/
  my-feature/
    api/          # API服务层
    components/   # 功能专属组件
    hooks/        # 自定义Hooks
    helpers/      # 工具函数
    types/        # TypeScript类型
📖 完整指南:resources/file-organization.md

🎨 Styling

🎨 样式设计

Inline vs Separate:
  • <100 lines: Inline
    const styles: Record<string, SxProps<Theme>>
  • 100 lines: Separate
    .styles.ts
    file
Primary Method:
  • Use
    sx
    prop for MUI components
  • Type-safe with
    SxProps<Theme>
  • Theme access:
    (theme) => theme.palette.primary.main
MUI v7 Grid:
typescript
<Grid size={{ xs: 12, md: 6 }}>  // ✅ v7 syntax
<Grid xs={12} md={6}>             // ❌ Old syntax
📖 Complete Guide: resources/styling-guide.md

内联 vs 单独文件:
  • 少于100行:内联
    const styles: Record<string, SxProps<Theme>>
  • 超过100行:使用单独的
    .styles.ts
    文件
主要方法:
  • 为MUI组件使用
    sx
    属性
  • 结合
    SxProps<Theme>
    确保类型安全
  • 主题访问:
    (theme) => theme.palette.primary.main
MUI v7 Grid:
typescript
<Grid size={{ xs: 12, md: 6 }}>  // ✅ v7语法
<Grid xs={12} md={6}>             // ❌ 旧语法
📖 完整指南:resources/styling-guide.md

🛣️ Routing

🛣️ 路由

TanStack Router - Folder-Based:
  • Directory:
    routes/my-route/index.tsx
  • Lazy load components
  • Use
    createFileRoute
  • Breadcrumb data in loader
Example:
typescript
import { createFileRoute } from '@tanstack/react-router';
import { lazy } from 'react';

const MyPage = lazy(() => import('@/features/my-feature/components/MyPage'));

export const Route = createFileRoute('/my-route/')({
    component: MyPage,
    loader: () => ({ crumb: 'My Route' }),
});
📖 Complete Guide: resources/routing-guide.md

TanStack Router - 基于目录:
  • 目录:
    routes/my-route/index.tsx
  • 懒加载组件
  • 使用
    createFileRoute
  • 在加载器中配置面包屑数据
示例:
typescript
import { createFileRoute } from '@tanstack/react-router';
import { lazy } from 'react';

const MyPage = lazy(() => import('@/features/my-feature/components/MyPage'));

export const Route = createFileRoute('/my-route/')({
    component: MyPage,
    loader: () => ({ crumb: 'My Route' }),
});
📖 完整指南:resources/routing-guide.md

⏳ Loading & Error States

⏳ 加载与错误状态

CRITICAL RULE: No Early Returns
typescript
// ❌ NEVER - Causes layout shift
if (isLoading) {
    return <LoadingSpinner />;
}

// ✅ ALWAYS - Consistent layout
<SuspenseLoader>
    <Content />
</SuspenseLoader>
Why: Prevents Cumulative Layout Shift (CLS), better UX
Error Handling:
  • Use
    useMuiSnackbar
    for user feedback
  • NEVER
    react-toastify
  • TanStack Query
    onError
    callbacks
📖 Complete Guide: resources/loading-and-error-states.md

关键规则:禁止提前返回
typescript
// ❌ 绝对不要这样做 - 会导致布局偏移
if (isLoading) {
    return <LoadingSpinner />;
}

// ✅ 正确做法 - 保持布局一致
<SuspenseLoader>
    <Content />
</SuspenseLoader>
原因: 避免累积布局偏移(CLS),提升用户体验
错误处理:
  • 使用
    useMuiSnackbar
    提供用户反馈
  • 绝对不要使用
    react-toastify
  • 结合TanStack Query的
    onError
    回调
📖 完整指南:resources/loading-and-error-states.md

⚡ Performance

⚡ 性能优化

Optimization Patterns:
  • useMemo
    : Expensive computations (filter, sort, map)
  • useCallback
    : Event handlers passed to children
  • React.memo
    : Expensive components
  • Debounced search (300-500ms)
  • Memory leak prevention (cleanup in useEffect)
📖 Complete Guide: resources/performance.md

优化模式:
  • useMemo
    :缓存昂贵计算(过滤、排序、映射)
  • useCallback
    :缓存传递给子组件的事件处理器
  • React.memo
    :优化重型组件
  • 搜索防抖(300-500ms)
  • 内存泄漏预防(在useEffect中清理)
📖 完整指南:resources/performance.md

📘 TypeScript

📘 TypeScript

Standards:
  • Strict mode, no
    any
    type
  • Explicit return types on functions
  • Type imports:
    import type { User } from '~types/user'
  • Component prop interfaces with JSDoc
📖 Complete Guide: resources/typescript-standards.md

规范:
  • 严格模式,禁止使用
    any
    类型
  • 函数显式声明返回类型
  • 类型导入:
    import type { User } from '~types/user'
  • 组件Props接口添加JSDoc注释
📖 完整指南:resources/typescript-standards.md

🔧 Common Patterns

🔧 通用模式

Covered Topics:
  • React Hook Form with Zod validation
  • DataGrid wrapper contracts
  • Dialog component standards
  • useAuth
    hook for current user
  • Mutation patterns with cache invalidation
📖 Complete Guide: resources/common-patterns.md

涵盖主题:
  • 结合Zod验证的React Hook Form
  • DataGrid包装器约定
  • 对话框组件规范
  • 获取当前用户的
    useAuth
    hook
  • 带缓存失效的Mutation模式
📖 完整指南:resources/common-patterns.md

📚 Complete Examples

📚 完整示例

Full working examples:
  • Modern component with all patterns
  • Complete feature structure
  • API service layer
  • Route with lazy loading
  • Suspense + useSuspenseQuery
  • Form with validation
📖 Complete Guide: resources/complete-examples.md

可运行完整示例:
  • 包含所有模式的现代组件
  • 完整的功能结构
  • API服务层
  • 带懒加载的路由
  • Suspense + useSuspenseQuery
  • 带验证的表单
📖 完整指南:resources/complete-examples.md

React-Specific Navigation Guide

React专属导航指南

Need to...Read this resource
Create a React componentcomponent-patterns.md
Fetch data with TanStack Querydata-fetching.md
Organize files/foldersfile-organization.md
Style with MUI v7styling-guide.md
Set up TanStack Routerrouting-guide.md
Handle loading/errorsloading-and-error-states.md
Optimize React performanceperformance.md
TypeScript typestypescript-standards.md
Forms/Auth/DataGridcommon-patterns.md
See full React examplescomplete-examples.md
Note: Resources above are React-specific. For Vue/Svelte/Angular, see framework sections in this document.

需要...阅读对应资源
创建React组件component-patterns.md
使用TanStack Query获取数据data-fetching.md
组织文件/文件夹file-organization.md
使用MUI v7设计样式styling-guide.md
配置TanStack Routerrouting-guide.md
处理加载/错误状态loading-and-error-states.md
优化React性能performance.md
TypeScript类型规范typescript-standards.md
表单/认证/DataGridcommon-patterns.md
查看完整React示例complete-examples.md
注意: 以上资源均为React专属。Vue/Svelte/Angular相关内容请查看本文档的对应框架章节。

Core Principles (All Frameworks)

核心原则(所有框架)

  1. Lazy Load Heavy Components: Routes, data grids, charts, editors, modals
  2. Consistent Loading States: Avoid layout shift with proper loading UI
  3. Type Safety: Use TypeScript for all components and APIs
  4. Component Composition: Small, focused components with clear responsibilities
  5. Unidirectional Data Flow: Props down, events up
  6. Performance First: Memoize expensive computations, virtual scrolling for lists
  7. Organized Features: Group related code (components, state, types, utilities)
  8. Framework Idioms: Use framework-specific patterns (hooks, composables, runes, services)
  1. 懒加载重型组件:路由、数据网格、图表、编辑器、模态框
  2. 一致的加载状态:通过合适的加载UI避免布局偏移
  3. 类型安全:所有组件和API均使用TypeScript
  4. 组件组合:职责单一、粒度精细的组件
  5. 单向数据流:Props向下传递,事件向上触发
  6. 性能优先:缓存昂贵计算,列表使用虚拟滚动
  7. 功能化组织:按功能分组相关代码(组件、状态、类型、工具)
  8. 框架原生模式:使用框架专属模式(hooks、组合式函数、runes、服务)

React-Specific Principles

React专属原则

  1. useSuspenseQuery: Primary data fetching pattern for new code
  2. No Early Returns: Prevents layout shift (use Suspense boundaries)
  3. Import Aliases: Use @/, ~types, ~components, ~features
  4. Styles Based on Size: <100 inline, >100 separate file
  1. useSuspenseQuery:新代码的首选数据获取模式
  2. 禁止提前返回:避免布局偏移(使用Suspense边界)
  3. 导入别名:使用@/、~types、~components、~features
  4. 按代码量选择样式方式:少于100行则内联,超过则单独文件

Vue-Specific Principles

Vue专属原则

  1. Composition API: Prefer over Options API for reusability
  2. Script Setup: Use for cleaner syntax and better performance
  3. Composables: Extract reusable logic like React hooks
  4. Pinia for State: Modern Vuex alternative with TypeScript support
  1. Composition API:为了复用性,优先于Options API
  2. Script Setup:更简洁的语法,更好的性能
  3. 组合式函数:提取可复用逻辑,类似React hooks
  4. Pinia管理状态:现代Vuex替代方案,支持TypeScript

Svelte-Specific Principles

Svelte专属原则

  1. Runes for Reactivity: Use $state, $derived, $effect (Svelte 5+)
  2. SvelteKit for Apps: Leverage file-based routing and server functions
  3. Minimal Stores: Runes reduce need for stores in components
  4. Progressive Enhancement: Build for no-JS, enhance with JS
  1. Runes实现响应式:使用$state、$derived、$effect(Svelte 5+)
  2. SvelteKit构建应用:利用基于文件的路由和服务器函数
  3. 精简Stores:Runes减少了组件中Stores的使用需求
  4. 渐进式增强:先构建无JS版本,再用JS增强

Angular-Specific Principles

Angular专属原则

  1. Standalone Components: Default since v17 (avoid NgModules)
  2. Signals for State: Prefer over RxJS for simple reactivity
  3. OnPush Detection: Optimize change detection
  4. Dependency Injection: Use inject() for modern DI

  1. 独立组件:v17起的默认方式(避免NgModules)
  2. Signals管理状态:简单响应式场景优先于RxJS
  3. OnPush变更检测:优化渲染性能
  4. 依赖注入:使用inject()实现现代依赖注入

Quick Reference: File Structure

文件结构速查

src/
  features/
    my-feature/
      api/
        myFeatureApi.ts       # API service
      components/
        MyFeature.tsx         # Main component
        SubComponent.tsx      # Related components
      hooks/
        useMyFeature.ts       # Custom hooks
        useSuspenseMyFeature.ts  # Suspense hooks
      helpers/
        myFeatureHelpers.ts   # Utilities
      types/
        index.ts              # TypeScript types
      index.ts                # Public exports

  components/
    SuspenseLoader/
      SuspenseLoader.tsx      # Reusable loader
    CustomAppBar/
      CustomAppBar.tsx        # Reusable app bar

  routes/
    my-route/
      index.tsx               # Route component
      create/
        index.tsx             # Nested route

src/
  features/
    my-feature/
      api/
        myFeatureApi.ts       # API服务
      components/
        MyFeature.tsx         # 主组件
        SubComponent.tsx      # 关联组件
      hooks/
        useMyFeature.ts       # 自定义Hooks
        useSuspenseMyFeature.ts  # Suspense Hooks
      helpers/
        myFeatureHelpers.ts   # 工具函数
      types/
        index.ts              # TypeScript类型
      index.ts                # 公共导出

  components/
    SuspenseLoader/
      SuspenseLoader.tsx      # 可复用加载组件
    CustomAppBar/
      CustomAppBar.tsx        # 可复用导航栏

  routes/
    my-route/
      index.tsx               # 路由组件
      create/
        index.tsx             # 嵌套路由

Modern Component Template (Quick Copy)

现代组件模板(快速复制)

typescript
import React, { useState, useCallback } from 'react';
import { Box, Paper } from '@mui/material';
import { useSuspenseQuery } from '@tanstack/react-query';
import { featureApi } from '../api/featureApi';
import type { FeatureData } from '~types/feature';

interface MyComponentProps {
    id: number;
    onAction?: () => void;
}

export const MyComponent: React.FC<MyComponentProps> = ({ id, onAction }) => {
    const [state, setState] = useState<string>('');

    const { data } = useSuspenseQuery({
        queryKey: ['feature', id],
        queryFn: () => featureApi.getFeature(id),
    });

    const handleAction = useCallback(() => {
        setState('updated');
        onAction?.();
    }, [onAction]);

    return (
        <Box sx={{ p: 2 }}>
            <Paper sx={{ p: 3 }}>
                {/* Content */}
            </Paper>
        </Box>
    );
};

export default MyComponent;
For complete examples, see resources/complete-examples.md

typescript
import React, { useState, useCallback } from 'react';
import { Box, Paper } from '@mui/material';
import { useSuspenseQuery } from '@tanstack/react-query';
import { featureApi } from '../api/featureApi';
import type { FeatureData } from '~types/feature';

interface MyComponentProps {
    id: number;
    onAction?: () => void;
}

export const MyComponent: React.FC<MyComponentProps> = ({ id, onAction }) => {
    const [state, setState] = useState<string>('');

    const { data } = useSuspenseQuery({
        queryKey: ['feature', id],
        queryFn: () => featureApi.getFeature(id),
    });

    const handleAction = useCallback(() => {
        setState('updated');
        onAction?.();
    }, [onAction]);

    return (
        <Box sx={{ p: 2 }}>
            <Paper sx={{ p: 3 }}>
                {/* 内容 */}
            </Paper>
        </Box>
    );
};

export default MyComponent;
完整示例请查看 resources/complete-examples.md

Vue 3 Development

Vue 3开发

Component Patterns

组件模式

Composition API - Modern Vue 3 approach with
<script setup>
:
vue
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import type { User } from '@/types/user'

interface Props {
  userId: number
}

const props = defineProps<Props>()
const emit = defineEmits<{
  update: [user: User]
}>()

const user = ref<User | null>(null)
const isLoading = ref(true)
const displayName = computed(() => user.value?.name ?? 'Unknown')

onMounted(async () => {
  user.value = await fetchUser(props.userId)
  isLoading.value = false
})

function handleUpdate() {
  if (user.value) emit('update', user.value)
}
</script>

<template>
  <div class="user-profile">
    <div v-if="isLoading">Loading...</div>
    <div v-else>
      <h2>{{ displayName }}</h2>
      <button @click="handleUpdate">Update</button>
    </div>
  </div>
</template>

<style scoped>
.user-profile {
  padding: 1rem;
}
</style>
Key Patterns:
  • <script setup>
    - Concise composition API syntax
  • defineProps<T>()
    - Type-safe props with generics
  • defineEmits<T>()
    - Type-safe events
  • ref()
    ,
    reactive()
    - Reactivity primitives
  • computed()
    - Derived state
  • watch()
    ,
    watchEffect()
    - Side effects
  • onMounted
    ,
    onUnmounted
    - Lifecycle hooks
Composition API - Vue 3的现代方式,结合
<script setup>
vue
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import type { User } from '@/types/user'

interface Props {
  userId: number
}

const props = defineProps<Props>()
const emit = defineEmits<{
  update: [user: User]
}>()

const user = ref<User | null>(null)
const isLoading = ref(true)
const displayName = computed(() => user.value?.name ?? 'Unknown')

onMounted(async () => {
  user.value = await fetchUser(props.userId)
  isLoading.value = false
})

function handleUpdate() {
  if (user.value) emit('update', user.value)
}
</script>

<template>
  <div class="user-profile">
    <div v-if="isLoading">加载中...</div>
    <div v-else>
      <h2>{{ displayName }}</h2>
      <button @click="handleUpdate">更新</button>
    </div>
  </div>
</template>

<style scoped>
.user-profile {
  padding: 1rem;
}
</style>
核心模式:
  • <script setup>
    - 简洁的Composition API语法
  • defineProps<T>()
    - 泛型支持的类型安全Props
  • defineEmits<T>()
    - 类型安全的事件
  • ref()
    reactive()
    - 响应式基础API
  • computed()
    - 派生状态
  • watch()
    watchEffect()
    - 副作用处理
  • onMounted
    onUnmounted
    - 生命周期钩子

State Management (Pinia)

状态管理(Pinia)

typescript
// stores/userStore.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useUserStore = defineStore('user', () => {
  // State
  const users = ref<User[]>([])
  const currentUser = ref<User | null>(null)

  // Getters
  const userCount = computed(() => users.value.length)
  const isAuthenticated = computed(() => currentUser.value !== null)

  // Actions
  async function fetchUsers() {
    users.value = await api.getUsers()
  }

  function setCurrentUser(user: User) {
    currentUser.value = user
  }

  return { users, currentUser, userCount, isAuthenticated, fetchUsers, setCurrentUser }
})

// Component usage
<script setup lang="ts">
import { useUserStore } from '@/stores/userStore'
const userStore = useUserStore()
</script>
typescript
// stores/userStore.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useUserStore = defineStore('user', () => {
  // 状态
  const users = ref<User[]>([])
  const currentUser = ref<User | null>(null)

  // Getters
  const userCount = computed(() => users.value.length)
  const isAuthenticated = computed(() => currentUser.value !== null)

  // Actions
  async function fetchUsers() {
    users.value = await api.getUsers()
  }

  function setCurrentUser(user: User) {
    currentUser.value = user
  }

  return { users, currentUser, userCount, isAuthenticated, fetchUsers, setCurrentUser }
})

// 组件中使用
<script setup lang="ts">
import { useUserStore } from '@/stores/userStore'
const userStore = useUserStore()
</script>

Routing (Vue Router)

路由(Vue Router)

typescript
// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/',
      component: () => import('@/views/HomeView.vue')
    },
    {
      path: '/users/:id',
      component: () => import('@/views/UserView.vue'),
      props: true
    }
  ]
})

// Component with route params
<script setup lang="ts">
import { useRoute, useRouter } from 'vue-router'

const route = useRoute()
const router = useRouter()
const userId = route.params.id

function goBack() {
  router.push('/')
}
</script>
typescript
// router/index.ts
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: '/',
      component: () => import('@/views/HomeView.vue')
    },
    {
      path: '/users/:id',
      component: () => import('@/views/UserView.vue'),
      props: true
    }
  ]
})

// 带路由参数的组件
<script setup lang="ts">
import { useRoute, useRouter } from 'vue-router'

const route = useRoute()
const router = useRouter()
const userId = route.params.id

function goBack() {
  router.push('/')
}
</script>

Data Fetching Patterns

数据获取模式

Composables - Reusable logic:
typescript
// composables/useUser.ts
import { ref, type Ref } from 'vue'

export function useUser(id: Ref<number>) {
  const user = ref<User | null>(null)
  const loading = ref(false)
  const error = ref<Error | null>(null)

  async function fetchUser() {
    loading.value = true
    try {
      user.value = await api.getUser(id.value)
    } catch (e) {
      error.value = e as Error
    } finally {
      loading.value = false
    }
  }

  watchEffect(() => {
    fetchUser()
  })

  return { user, loading, error, refetch: fetchUser }
}

// Usage in component
<script setup lang="ts">
const props = defineProps<{ userId: number }>()
const { user, loading, error } = useUser(toRef(props, 'userId'))
</script>
Nuxt.js Server-Side:
vue
<script setup lang="ts">
// Nuxt auto-imports composables
const { data: user, pending, error } = await useFetch(`/api/users/${route.params.id}`)
</script>
组合式函数 - 可复用逻辑:
typescript
// composables/useUser.ts
import { ref, type Ref } from 'vue'

export function useUser(id: Ref<number>) {
  const user = ref<User | null>(null)
  const loading = ref(false)
  const error = ref<Error | null>(null)

  async function fetchUser() {
    loading.value = true
    try {
      user.value = await api.getUser(id.value)
    } catch (e) {
      error.value = e as Error
    } finally {
      loading.value = false
    }
  }

  watchEffect(() => {
    fetchUser()
  })

  return { user, loading, error, refetch: fetchUser }
}

// 组件中使用
<script setup lang="ts">
const props = defineProps<{ userId: number }>()
const { user, loading, error } = useUser(toRef(props, 'userId'))
</script>
Nuxt.js服务端渲染:
vue
<script setup lang="ts">
// Nuxt自动导入组合式函数
const { data: user, pending, error } = await useFetch(`/api/users/${route.params.id}`)
</script>

Vue 3 Best Practices

Vue 3最佳实践

  • Composition API over Options API - Better TypeScript support, reusability
  • Script setup - Reduces boilerplate, automatic registration
  • Pinia over Vuex - Simpler API, better TypeScript, composition API compatible
  • Composables - Extract reusable logic (like React hooks)
  • v-memo - Optimize expensive renders (similar to React.memo)
  • defineOptions - Set component options in script setup
  • Shallow reactive - Use
    shallowRef()
    for large objects

  • 优先使用Composition API而非Options API - 更好的TypeScript支持,更高的复用性
  • 使用Script Setup - 减少样板代码,自动注册
  • Pinia替代Vuex - 更简洁的API,更好的TypeScript支持,兼容Composition API
  • 组合式函数 - 提取可复用逻辑(类似React hooks)
  • v-memo - 优化昂贵渲染(类似React.memo)
  • defineOptions - 在script setup中设置组件选项
  • 浅响应式 - 大型对象使用
    shallowRef()

Svelte 5 Development

Svelte 5开发

Runes-Based Reactivity

基于Runes的响应式

Svelte 5 Runes - New reactivity system:
svelte
<script lang="ts">
import type { User } from '$lib/types/user'

interface Props {
  userId: number
  onUpdate?: (user: User) => void
}

let { userId, onUpdate }: Props = $props()

// Reactive state with $state
let user = $state<User | null>(null)
let isLoading = $state(true)

// Derived state with $derived
let displayName = $derived(user?.name ?? 'Unknown')
let userAge = $derived.by(() => {
  if (!user?.birthDate) return null
  return calculateAge(user.birthDate)
})

// Effects with $effect
$effect(() => {
  // Runs when userId changes
  loadUser(userId)
})

async function loadUser(id: number) {
  isLoading = true
  user = await fetchUser(id)
  isLoading = false
}

function handleUpdate() {
  if (user) onUpdate?.(user)
}
</script>

{#if isLoading}
  <div>Loading...</div>
{:else if user}
  <div class="user-profile">
    <h2>{displayName}</h2>
    {#if userAge}
      <p>Age: {userAge}</p>
    {/if}
    <button onclick={handleUpdate}>Update</button>
  </div>
{/if}

<style>
.user-profile {
  padding: 1rem;
}
</style>
Svelte 5 Runes:
  • $state()
    - Reactive state (replaces
    let
    for reactivity)
  • $derived
    - Computed values (replaces
    $:
    )
  • $derived.by()
    - Complex derived state
  • $effect()
    - Side effects (replaces
    $:
    statements)
  • $props()
    - Component props with destructuring
  • $bindable()
    - Two-way binding for props
  • $inspect()
    - Debugging reactive values
Svelte 5 Runes - 全新响应式系统:
svelte
<script lang="ts">
import type { User } from '$lib/types/user'

interface Props {
  userId: number
  onUpdate?: (user: User) => void
}

let { userId, onUpdate }: Props = $props()

// 使用$state定义响应式状态
let user = $state<User | null>(null)
let isLoading = $state(true)

// 使用$derived定义派生状态
let displayName = $derived(user?.name ?? 'Unknown')
let userAge = $derived.by(() => {
  if (!user?.birthDate) return null
  return calculateAge(user.birthDate)
})

// 使用$effect处理副作用
$effect(() => {
  // 当userId变化时执行
  loadUser(userId)
})

async function loadUser(id: number) {
  isLoading = true
  user = await fetchUser(id)
  isLoading = false
}

function handleUpdate() {
  if (user) onUpdate?.(user)
}
</script>

{#if isLoading}
  <div>加载中...</div>
{:else if user}
  <div class="user-profile">
    <h2>{displayName}</h2>
    {#if userAge}
      <p>年龄: {userAge}</p>
    {/if}
    <button onclick={handleUpdate}>更新</button>
  </div>
{/if}

<style>
.user-profile {
  padding: 1rem;
}
</style>
Svelte 5 Runes:
  • $state()
    - 响应式状态(替代原有的let实现响应式)
  • $derived
    - 派生状态(替代$:)
  • $derived.by()
    - 复杂派生状态
  • $effect()
    - 副作用处理(替代$:语句)
  • $props()
    - 支持解构的组件Props
  • $bindable()
    - 支持双向绑定的Props
  • $inspect()
    - 调试响应式值

State Management (Svelte Stores)

状态管理(Svelte Stores)

typescript
// stores/user.ts
import { writable, derived, readonly } from 'svelte/store'

function createUserStore() {
  const { subscribe, set, update } = writable<User[]>([])

  return {
    subscribe,
    setUsers: (users: User[]) => set(users),
    addUser: (user: User) => update(users => [...users, user]),
    removeUser: (id: number) => update(users => users.filter(u => u.id !== id)),
    reset: () => set([])
  }
}

export const users = createUserStore()
export const userCount = derived(users, $users => $users.length)

// Component usage (Svelte 4 style)
<script>
import { users } from '$lib/stores/user'
</script>

<p>Total users: {$users.length}</p>

// Or with runes (Svelte 5)
<script>
import { users } from '$lib/stores/user'
let currentUsers = $state($users)
</script>
typescript
// stores/user.ts
import { writable, derived, readonly } from 'svelte/store'

function createUserStore() {
  const { subscribe, set, update } = writable<User[]>([])

  return {
    subscribe,
    setUsers: (users: User[]) => set(users),
    addUser: (user: User) => update(users => [...users, user]),
    removeUser: (id: number) => update(users => users.filter(u => u.id !== id)),
    reset: () => set([])
  }
}

export const users = createUserStore()
export const userCount = derived(users, $users => $users.length)

// 组件中使用(Svelte 4风格)
<script>
import { users } from '$lib/stores/user'
</script>

<p>用户总数: {$users.length}</p>

// 或使用Runes(Svelte 5)
<script>
import { users } from '$lib/stores/user'
let currentUsers = $state($users)
</script>

SvelteKit Routing & Data Loading

SvelteKit路由与数据加载

typescript
// src/routes/users/[id]/+page.ts
import type { PageLoad } from './$types'

export const load: PageLoad = async ({ params, fetch }) => {
  const user = await fetch(`/api/users/${params.id}`).then(r => r.json())

  return {
    user
  }
}

// src/routes/users/[id]/+page.svelte
<script lang="ts">
import type { PageData } from './$types'

let { data }: { data: PageData } = $props()
let { user } = $derived(data)
</script>

<h1>{user.name}</h1>
SvelteKit Patterns:
  • +page.svelte
    - Page component
  • +page.ts
    - Page data loading (runs on server and client)
  • +page.server.ts
    - Server-only load functions
  • +layout.svelte
    - Shared layouts
  • +server.ts
    - API endpoints
  • Form actions - Progressive enhancement
typescript
// src/routes/users/[id]/+page.ts
import type { PageLoad } from './$types'

export const load: PageLoad = async ({ params, fetch }) => {
  const user = await fetch(`/api/users/${params.id}`).then(r => r.json())

  return {
    user
  }
}

// src/routes/users/[id]/+page.svelte
<script lang="ts">
import type { PageData } from './$types'

let { data }: { data: PageData } = $props()
let { user } = $derived(data)
</script>

<h1>{user.name}</h1>
SvelteKit模式:
  • +page.svelte
    - 页面组件
  • +page.ts
    - 页面数据加载(服务端和客户端均会执行)
  • +page.server.ts
    - 仅服务端执行的加载函数
  • +layout.svelte
    - 共享布局
  • +server.ts
    - API端点
  • 表单操作 - 渐进式增强

Svelte 5 Best Practices

Svelte 5最佳实践

  • Use Runes - Modern reactivity (Svelte 5+)
  • Explicit reactivity - Use
    $state()
    instead of implicit
    let
  • $derived over $: - Clearer intent, better optimization
  • Component composition - Use slots and snippets
  • SvelteKit for apps - Full-stack framework with routing, SSR
  • Minimize stores - Runes reduce need for stores in components
  • Progressive enhancement - Use form actions for better UX

  • 使用Runes - 现代响应式系统(Svelte 5+)
  • 显式响应式 - 使用
    $state()
    而非隐式的let
  • 优先使用$derived而非$: - 意图更清晰,优化更友好
  • 组件组合 - 使用插槽和代码片段
  • SvelteKit构建应用 - 全栈框架,支持路由、SSR
  • 精简Stores - Runes减少了组件中Stores的使用需求
  • 渐进式增强 - 使用表单操作提升用户体验

Angular Development

Angular开发

Standalone Components (Modern)

独立组件(现代方式)

typescript
// user-profile.component.ts
import { Component, Input, Output, EventEmitter, signal, computed } from '@angular/core'
import { CommonModule } from '@angular/common'
import type { User } from '@/types/user'

@Component({
  selector: 'app-user-profile',
  standalone: true,
  imports: [CommonModule],
  template: `
    <div class="user-profile" *ngIf="!isLoading(); else loading">
      <h2>{{ displayName() }}</h2>
      <p>Age: {{ userAge() }}</p>
      <button (click)="handleUpdate()">Update</button>
    </div>
    <ng-template #loading>
      <div>Loading...</div>
    </ng-template>
  `,
  styles: [`
    .user-profile {
      padding: 1rem;
    }
  `]
})
export class UserProfileComponent {
  @Input({ required: true }) userId!: number
  @Output() userUpdate = new EventEmitter<User>()

  // Signals - reactive primitives
  user = signal<User | null>(null)
  isLoading = signal(true)

  // Computed signals
  displayName = computed(() => this.user()?.name ?? 'Unknown')
  userAge = computed(() => {
    const birthDate = this.user()?.birthDate
    return birthDate ? this.calculateAge(birthDate) : null
  })

  async ngOnInit() {
    this.user.set(await this.fetchUser(this.userId))
    this.isLoading.set(false)
  }

  handleUpdate() {
    const currentUser = this.user()
    if (currentUser) this.userUpdate.emit(currentUser)
  }
}
Angular Signals - New reactivity system (v16+):
  • signal()
    - Writable reactive value
  • computed()
    - Derived state
  • effect()
    - Side effects
  • .set()
    ,
    .update()
    - Modify signal values
  • ()
    - Read signal value (call as function)
typescript
// user-profile.component.ts
import { Component, Input, Output, EventEmitter, signal, computed } from '@angular/core'
import { CommonModule } from '@angular/common'
import type { User } from '@/types/user'

@Component({
  selector: 'app-user-profile',
  standalone: true,
  imports: [CommonModule],
  template: `
    <div class="user-profile" *ngIf="!isLoading(); else loading">
      <h2>{{ displayName() }}</h2>
      <p>年龄: {{ userAge() }}</p>
      <button (click)="handleUpdate()">更新</button>
    </div>
    <ng-template #loading>
      <div>加载中...</div>
    </ng-template>
  `,
  styles: [`
    .user-profile {
      padding: 1rem;
    }
  `]
})
export class UserProfileComponent {
  @Input({ required: true }) userId!: number
  @Output() userUpdate = new EventEmitter<User>()

  // Signals - 响应式基础API
  user = signal<User | null>(null)
  isLoading = signal(true)

  // 计算型Signals
  displayName = computed(() => this.user()?.name ?? 'Unknown')
  userAge = computed(() => {
    const birthDate = this.user()?.birthDate
    return birthDate ? this.calculateAge(birthDate) : null
  })

  async ngOnInit() {
    this.user.set(await this.fetchUser(this.userId))
    this.isLoading.set(false)
  }

  handleUpdate() {
    const currentUser = this.user()
    if (currentUser) this.userUpdate.emit(currentUser)
  }
}
Angular Signals - 全新响应式系统(v16+):
  • signal()
    - 可写响应式值
  • computed()
    - 派生状态
  • effect()
    - 副作用处理
  • .set()
    .update()
    - 修改Signal值
  • ()
    - 读取Signal值(作为函数调用)

State Management (Services + Signals)

状态管理(服务 + Signals)

typescript
// services/user.service.ts
import { Injectable, signal, computed } from '@angular/core'
import { HttpClient } from '@angular/common/http'

@Injectable({ providedIn: 'root' })
export class UserService {
  private users = signal<User[]>([])
  private currentUser = signal<User | null>(null)

  // Public computed signals
  readonly userCount = computed(() => this.users().length)
  readonly isAuthenticated = computed(() => this.currentUser() !== null)

  constructor(private http: HttpClient) {}

  async fetchUsers() {
    const users = await this.http.get<User[]>('/api/users').toPromise()
    this.users.set(users)
  }

  setCurrentUser(user: User) {
    this.currentUser.set(user)
  }
}

// Component usage
export class MyComponent {
  constructor(public userService: UserService) {}

  // Access in template
  // {{ userService.userCount() }}
}
typescript
// services/user.service.ts
import { Injectable, signal, computed } from '@angular/core'
import { HttpClient } from '@angular/common/http'

@Injectable({ providedIn: 'root' })
export class UserService {
  private users = signal<User[]>([])
  private currentUser = signal<User | null>(null)

  // 公共计算型Signals
  readonly userCount = computed(() => this.users().length)
  readonly isAuthenticated = computed(() => this.currentUser() !== null)

  constructor(private http: HttpClient) {}

  async fetchUsers() {
    const users = await this.http.get<User[]>('/api/users').toPromise()
    this.users.set(users)
  }

  setCurrentUser(user: User) {
    this.currentUser.set(user)
  }
}

// 组件中使用
export class MyComponent {
  constructor(public userService: UserService) {}

  // 在模板中访问
  // {{ userService.userCount() }}
}

Routing (Angular Router)

路由(Angular Router)

typescript
// app.routes.ts
import { Routes } from '@angular/router'

export const routes: Routes = [
  {
    path: '',
    loadComponent: () => import('./home/home.component').then(m => m.HomeComponent)
  },
  {
    path: 'users/:id',
    loadComponent: () => import('./users/user-detail.component').then(m => m.UserDetailComponent)
  }
]

// Component with route params
import { Component } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'

export class UserDetailComponent {
  userId = signal<string>('')

  constructor(
    private route: ActivatedRoute,
    private router: Router
  ) {
    this.userId.set(this.route.snapshot.paramMap.get('id') ?? '')
  }

  goBack() {
    this.router.navigate(['/'])
  }
}
typescript
// app.routes.ts
import { Routes } from '@angular/router'

export const routes: Routes = [
  {
    path: '',
    loadComponent: () => import('./home/home.component').then(m => m.HomeComponent)
  },
  {
    path: 'users/:id',
    loadComponent: () => import('./users/user-detail.component').then(m => m.UserDetailComponent)
  }
]

// 带路由参数的组件
import { Component } from '@angular/core'
import { ActivatedRoute, Router } from '@angular/router'

export class UserDetailComponent {
  userId = signal<string>('')

  constructor(
    private route: ActivatedRoute,
    private router: Router
  ) {
    this.userId.set(this.route.snapshot.paramMap.get('id') ?? '')
  }

  goBack() {
    this.router.navigate(['/'])
  }
}

Data Fetching (RxJS + Signals)

数据获取(RxJS + Signals)

typescript
import { Component, signal } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { toSignal } from '@angular/core/rxjs-interop'

export class UserListComponent {
  private http = inject(HttpClient)

  // Convert Observable to Signal
  users = toSignal(this.http.get<User[]>('/api/users'), { initialValue: [] })

  // Or manual signal management
  manualUsers = signal<User[]>([])

  async loadUsers() {
    const users = await this.http.get<User[]>('/api/users').toPromise()
    this.manualUsers.set(users)
  }
}
typescript
import { Component, signal } from '@angular/core'
import { HttpClient } from '@angular/common/http'
import { toSignal } from '@angular/core/rxjs-interop'

export class UserListComponent {
  private http = inject(HttpClient)

  // 将Observable转换为Signal
  users = toSignal(this.http.get<User[]>('/api/users'), { initialValue: [] })

  // 或手动管理Signal
  manualUsers = signal<User[]>([])

  async loadUsers() {
    const users = await this.http.get<User[]>('/api/users').toPromise()
    this.manualUsers.set(users)
  }
}

Angular Best Practices

Angular最佳实践

  • Standalone components - Default since v17 (no NgModules)
  • Signals over RxJS - Simpler reactivity for state
  • toSignal - Convert Observables to Signals when needed
  • inject() - Modern dependency injection (no constructor)
  • Lazy loading - Use
    loadComponent
    for routes
  • OnPush change detection - Optimize rendering
  • Typed forms - Use
    FormGroup<T>
    for type safety

  • 独立组件 - v17起默认方式(无需NgModules)
  • 优先使用Signals而非RxJS - 状态管理更简单
  • toSignal - 必要时将Observables转换为Signals
  • inject() - 现代依赖注入方式(无需构造函数)
  • 懒加载 - 路由中使用
    loadComponent
  • OnPush变更检测 - 优化渲染性能
  • 类型安全表单 - 使用
    FormGroup<T>
    确保类型安全

Framework-Agnostic Patterns

跨框架通用模式

State Management Comparison

状态管理对比

PatternReactVue 3Svelte 5Angular
Local State
useState
ref()
$state()
signal()
Derived State
useMemo
computed()
$derived
computed()
Side Effects
useEffect
watch/watchEffect
$effect()
effect()
Global StateZustand/ContextPiniaStoresServices
Async StateTanStack QueryVueQuery/ComposablesStoresRxJS/Signals
模式ReactVue 3Svelte 5Angular
局部状态
useState
ref()
$state()
signal()
派生状态
useMemo
computed()
$derived
computed()
副作用
useEffect
watch/watchEffect
$effect()
effect()
全局状态Zustand/ContextPiniaStores服务
异步状态TanStack QueryVueQuery/组合式函数StoresRxJS/Signals

Component Composition Patterns

组件组合模式

Props/Events Pattern (All frameworks):
  • Parent passes data down via props
  • Child emits events upward
  • Unidirectional data flow
Slots/Children Pattern:
typescript
// React
<Layout>
  <Header />
  <Content />
</Layout>

// Vue
<Layout>
  <template #header><Header /></template>
  <template #content><Content /></template>
</Layout>

// Svelte
<Layout>
  <Header slot="header" />
  <Content slot="content" />
</Layout>

// Angular
<app-layout>
  <app-header header></app-header>
  <app-content content></app-content>
</app-layout>
Props/Events模式(所有框架):
  • 父组件通过Props向下传递数据
  • 子组件通过事件向上传递消息
  • 单向数据流
插槽/子组件模式:
typescript
// React
<Layout>
  <Header />
  <Content />
</Layout>

// Vue
<Layout>
  <template #header><Header /></template>
  <template #content><Content /></template>
</Layout>

// Svelte
<Layout>
  <Header slot="header" />
  <Content slot="content" />
</Layout>

// Angular
<app-layout>
  <app-header header></app-header>
  <app-content content></app-content>
</app-layout>

Routing Patterns

路由模式

File-Based Routing:
  • Next.js (React), Nuxt (Vue), SvelteKit (Svelte)
  • Folder structure defines routes
  • [id]
    for dynamic segments
Programmatic Routing:
  • React Router, Vue Router, Angular Router
  • Define routes in config
  • More flexible but more verbose
基于文件的路由:
  • Next.js(React)、Nuxt(Vue)、SvelteKit(Svelte)
  • 目录结构定义路由
  • [id]
    表示动态路由段
编程式路由:
  • React Router、Vue Router、Angular Router
  • 在配置中定义路由
  • 更灵活但更繁琐

Performance Optimization

性能优化

Universal Techniques:
  1. Code splitting - Lazy load routes and heavy components
  2. Memoization - Cache expensive computations
  3. Virtual scrolling - Render only visible items
  4. Debouncing - Throttle expensive operations (search, resize)
  5. Image optimization - Lazy load, responsive images, modern formats
  6. Bundle analysis - Identify and remove large dependencies
Framework-Specific:
  • React:
    React.memo
    ,
    useMemo
    ,
    useCallback
    , Suspense
  • Vue:
    v-memo
    ,
    shallowRef
    ,
    markRaw
    , KeepAlive
  • Svelte: Automatic optimization,
    $derived
    , minimal runtime
  • Angular: OnPush, signals, trackBy, pure pipes

通用技巧:
  1. 代码分割 - 懒加载路由和重型组件
  2. 缓存 - 缓存昂贵计算
  3. 虚拟滚动 - 仅渲染可见项
  4. 防抖 - 节流昂贵操作(搜索、 resize)
  5. 图片优化 - 懒加载、响应式图片、现代格式
  6. 包分析 - 识别并移除大型依赖
框架专属技巧:
  • React:
    React.memo
    useMemo
    useCallback
    、Suspense
  • Vue:
    v-memo
    shallowRef
    markRaw
    、KeepAlive
  • Svelte: 自动优化、
    $derived
    、轻量运行时
  • Angular: OnPush、Signals、trackBy、纯管道

Related Skills

相关技能

IMPORTANT: For UI/UX design work, invoke the specialized skill:
Skill("ui-ux-pro-max")  → UI/UX design, visual hierarchy, color theory, spacing, typography
UI/Design:
  • ui-ux-pro-max: UI/UX design principles, visual hierarchy, color theory, spacing systems, typography. USE THIS for design decisions, beautifying UIs, choosing colors/fonts, layout design.
  • ui-design-system: Component design systems, accessibility, design tokens
  • ui-styling: Tailwind CSS, styling patterns for all frameworks
Backend Integration:
  • backend-development: API patterns that frontend consumes
  • better-auth: Authentication implementation (works with all frameworks)
Full-Stack Frameworks:
  • web-frameworks: Next.js (React), Nuxt (Vue), SvelteKit (Svelte) deep dive
Development:
  • debugging: Framework-agnostic debugging strategies
  • refactoring-expert: Code quality and refactoring patterns
  • chrome-devtools: Browser debugging, performance profiling
重要提示: 若涉及UI/UX设计工作,请调用专属技能:
Skill("ui-ux-pro-max")  → UI/UX设计、视觉层级、色彩理论、间距、排版
UI/设计类:
  • ui-ux-pro-max:UI/UX设计原则、视觉层级、色彩理论、间距系统、排版。设计决策、UI美化、颜色/字体选择、布局设计请使用本技能
  • ui-design-system:组件设计系统、可访问性、设计令牌
  • ui-styling:Tailwind CSS、全框架样式模式
后端集成类:
  • backend-development:前端对接的API模式
  • better-auth:全框架认证实现方案
全栈框架类:
  • web-frameworks:Next.js(React)、Nuxt(Vue)、SvelteKit(Svelte)深度指南
开发工具类:
  • debugging:跨框架调试策略
  • refactoring-expert:代码质量与重构模式
  • chrome-devtools:浏览器调试、性能分析

When to Invoke ui-ux-pro-max

何时调用ui-ux-pro-max

Call
Skill("ui-ux-pro-max")
when:
  • Designing new UI components or pages
  • Choosing color palettes, typography, or spacing
  • Improving visual hierarchy or layout
  • Making interfaces look professional/modern/clean
  • User mentions: ugly, inconsistent, cluttered, needs design help
  • Building dashboards, admin panels, or SaaS interfaces

Skill Status: Multi-framework coverage with progressive disclosure
当以下场景出现时,请调用
Skill("ui-ux-pro-max")
  • 设计新UI组件或页面
  • 选择调色板、排版或间距
  • 优化视觉层级或布局
  • 让界面更专业/现代/简洁
  • 用户提及:丑陋、不一致、杂乱、需要设计帮助
  • 构建仪表盘、管理后台或SaaS界面

技能状态:覆盖多框架,支持渐进式学习