React、Vue、Angular 的选择本质是匹配团队对响应式原理的理解深度与框架抽象层级,而非单纯性能或学习成本——选错导致持续增厚技术债。

框架本质是约束换效率:不是帮你写代码,是帮你避免重写同一类代码
所谓框架,就是提前替你决定「组件怎么定义」「状态怎么流转」「错误怎么冒泡」「路由怎么拆包」。它不减少工作量,但消灭重复决策。比如:createBrowserRouter(React Router v6.4+)强制你把路由声明为嵌套对象,而不是手动监听 location.pathname;ngModule(Angular)要求你显式声明依赖,否则 HttpClient 就是 undefined;defineComponent(Vue 3)用泛型推导 props 类型,省掉手写 PropType 的漏判风险。
- 没框架 → 每个新页面都要重写权限校验逻辑、loading 状态管理、错误边界包装
- 有框架 → 这些变成配置项或装饰器,改一处,全链路生效
- 坑点:框架的“约定”一旦和业务强耦合(比如 Vue 的
setup()+ref()混用reactive()),后期迁移成本远高于初期学习成本
React 适合「已有 JS 功底,且后端已定型」的团队
React 最常被误用的场景,是拿它当 Angular 用:硬套 Redux Toolkit 管理全局状态,结果 80% 的 state 根本跨不了组件边界。它真正的优势在「松耦合可替换」——useEffect 可以随时换成 useSyncExternalStore 接入外部状态源,ReactDOM.createRoot 能无缝切到 React Server Components 架构。
- 适用信号:团队熟悉 Promise / async-await,已有 Node.js 或 Go 后端,接口返回结构稳定
- 避坑重点:
useState初始化函数只执行一次,别在里面写fetch();useMemo依赖数组漏写会导致 UI 不更新,但控制台不报错 - 性能真相:虚拟 DOM 并不总比直接操作快——列表项用
key={Math.random()}会强制重渲染全部节点,比 Angular 的OnPush更伤
Vue 的「渐进式」不是营销话术,是真实存在的逃生通道
Vue 的核心价值不在语法糖,而在设计上预留了三条退路:v-if 和 v-show 分离显示逻辑与 DOM 存在;shallowRef 和 markRaw 能绕过响应式系统;defineAsyncComponent 支持按需降级到传统 script 标签加载。这意味着你可以用 Vue 写一个独立组件嵌入 jQuery 旧系统,也能把它整个升级成微前端子应用。
- 典型误用:在
computed里调用 API,以为能缓存请求结果——其实它只缓存返回值,不阻止重复请求 - 关键配置:
compilerOptions.isCustomElement必须设为name => name.startsWith('wc-')才能让自定义元素跳过编译,否则会被当成普通标签忽略 - 兼容性雷区:Vue 3 的
ref()在模板中自动解包,但传给第三方库(如 ECharts)时必须用.value,否则图表不渲染
Angular 的严格性不是负担,是防止“上线后才发现模块循环引用”的安全带
Angular 的 CLI 生成的 ng generate module 默认带 forRoot(),这不是仪式感——它强制你在根模块注册服务,避免子模块多次提供同一服务导致单例失效。它的 strictTemplates 编译选项能在构建时报出 *ngIf="user?.name" 中 user 可能为 null 的类型错误,而 React + TypeScript 默认放过这种隐患。
立即学习“前端免费学习笔记(深入)”;
- 适合场景:金融/医疗类系统,要求静态分析覆盖 100% 的数据流路径,CI 流程中不能容忍 runtime type error
- 真实代价:
ng serve启动耗时是vite build的 3–5 倍,但热更新速度几乎无感知——因为变更检测只检查标记为OnPush的组件 - 隐蔽陷阱:
async管道在组件销毁后仍可能触发next(),必须配合takeUntilDestroyed()(Angular v16+),否则内存泄漏且控制台静默
ref 和 reactive 的边界,Angular 要求你接受它的 DI 容器调度逻辑。选错,不是跑不起来,是每次加功能都在给技术债计息。










