你学完了 HTML、CSS、JavaScript,能写个会动的小页面了。但一旦项目变大——几十个按钮、上百条数据、多个页面互相跳转——你会发现原生 JS 开始”反噬”:改一个数据要手动去 DOM 里找元素、改文本、改样式,逻辑散落一地,改一处崩三处。
这正是前端框架(Vue、React、Angular、Svelte)要解决的问题。它们不是”更难的 JS”,而是”帮你在复杂场景下管理界面的思维方式”。这一篇我们讲清楚:框架到底解决了什么、什么是”状态驱动视图”、Vue 和 React 怎么选。
原生 JS 的痛:手动操作 DOM
回忆一下你之前写的点击改文字:先 getElementById 找到元素,再 textContent = ... 改它。这在小demo里没问题,但真实页面里:
- 数据变了,你要手动同步到 DOM(找元素、改内容、改 class、改列表),漏一个就界面错乱。
- 列表数据增删,你要手动
createElement/removeChild,代码又臭又长。 - 多个地方展示同一份数据(如”购物车数量”在顶部和弹窗都显示),改一处得手动改两处,极易不一致。
本质问题:数据和界面是”两张皮”,你得自己当胶水把它们粘起来。框架要做的,就是”让界面自动跟着数据变”,你只管改数据。
核心思想一:状态驱动视图
框架的核心范式是:你维护”状态(数据)“,界面由状态自动渲染出来。数据变了,框架负责把变化反映到屏幕上,你不再碰 DOM。
打个比方:原生 JS 像”手工画画”——每改一笔都要自己拿笔补;框架像”拍照”——你摆好模特(状态),按一下快门(渲染),照片(界面)就出来了。改了模特姿势,再按一次快门即可,不用自己改画。
// 伪代码:你只改状态
const state = { count: 0 };
function increment() {
state.count++; // 只改数据
render(); // 框架自动根据 state 重画界面
}
你完全不用写”找到那个数字元素、把它的文本改成新值”——那是框架的活。这就是声明式:你声明”界面应该长什么样(基于状态)“,而不是”一步步命令怎么改界面(命令式)“。
核心思想二:组件化
框架把界面拆成一个个可复用、自包含的”组件”。一个按钮是组件、一个卡片是组件、一整个页面也是组件(由小组件拼成)。
好处:
- 复用:
<Button>写一次,全站用一百次,改样式只改一处。 - 隔离:每个组件管自己的结构和逻辑,互不干扰。
- 组合:大组件套小组件,像搭乐高,页面再复杂也是组件的树。
<!-- Vue 风格示意 -->
<Page>
<Header />
<Sidebar />
<Content>
<ArticleCard v-for="a in articles" :key="a.id" :data="a" />
</Content>
</Page>
核心思想三:虚拟 DOM 与高效更新
你可能会问:状态变了,框架难道把整个页面重画一遍?那不卡吗?框架用虚拟 DOM(Virtual DOM) 解决:它在内存里维护一份”界面的 JS 描述”,状态变化时先算出”新旧两版描述的差异”,只把真正变了的那一小块更新到真实 DOM。你享受”整体重画”的简单思维,却只付出”局部更新”的性能代价。
小知识:Svelte 等框架甚至不用虚拟 DOM,而是在编译期就把”状态→界面”的依赖直接编译成高效的命令式更新。但”状态驱动视图”的思想是一致的。
Vue vs React:怎么选
这是新手最常问的。两者都能做一样的事,哲学略有不同:
| 维度 | Vue | React |
|---|---|---|
| 模板写法 | 单文件组件(HTML 模板 + JS + CSS 一体) | JSX(JS 里直接写 HTML 标签) |
| 上手曲线 | 更平缓,文档友好,约定多 | 更灵活,但需要自己选生态(路由/状态库) |
| 状态管理 | 响应式系统(改了自动追踪) | 显式 setState/useState |
| 生态 | 官方一统(Vue Router、Pinia) | 社区百花齐放 |
| 适合 | 想快上手、团队规范统一 | 喜欢灵活、大型应用、愿意搭基建 |
给新手的实在建议:别在”选哪个”上纠结太久。两者核心思想(状态驱动、组件化、声明式)完全相通,学会一个,另一个一周就能上手。挑一个顺眼的先精通,比”两个都学一点”强十倍。本文系列会同时覆盖 Vue 和 React 的基础,让你建立通用认知。
常见新手坑
- 想用框架却还在手动操作 DOM:框架里基本不该出现
document.getElementById+ 改文本,那是回到原生思维。改状态让框架渲染。 - 把框架当”更难的 JS”吓退:框架是帮你省事的,不是加难度的。先接受”状态驱动”思维,再学语法。
- 过度拆分或从不拆分组件:一个组件写了五百行(该拆),或每个
div都封成组件(过度)。按”可复用 + 单一职责”拆。 - 在错误时机改状态:比如在渲染期间直接改状态导致死循环。理解框架的生命周期/副作用机制再动手。
- 纠结选型耽误进度:Vue/React 都能成事,选定一个深入,别反复横跳。
实战:用框架思维重写”计数器”
原生 JS 版你要手动找元素改文本。框架思维下,你只写”状态 + 基于状态的界面”:
<!-- Vue 示意 -->
<script setup>
import { ref } from 'vue';
const count = ref(0); // 状态
const increment = () => count.value++; // 只改状态
</script>
<template>
<p>当前计数:{{ count }}</p> <!-- 界面绑定状态 -->
<button @click="increment">+1</button>
</template>
你没碰过一次 DOM,但点按钮数字就会变——因为 count 是响应式的,它变了,模板里 {{ count }} 自动重画。这就是框架带来的”数据→界面”自动同步。
新手怎么把框架思维建立起来
最大的门槛不是语法,而是从”命令式”切换到”声明式”。建议刻意练习:拿到一个交互需求,先问自己”界面需要哪些状态”,再想”状态怎么变成界面”,最后才写代码。别一上来就 getElementById。
另一个心法:先读官方教程的”思想”部分。Vue 和 React 官网都有”核心概念/哲学”章节,花一小时读透,比背十篇 API 文档都管用。框架的 API 会过时、会新增,但”状态驱动视图、组件化、声明式”这套思想十年不变。
还有,别急着上脚手架和构建工具。先用框架提供的”在线 playground”或 CDN 引入,写几个小组件感受响应式,再进入工程化(下一大类的主题)。先懂思想,再学工具,顺序反了容易迷失在配置里。
小测验:看看你掌握了没
- 问题一:框架解决原生 JS 的什么核心痛点?答案:数据和界面”两张皮”,要手动同步 DOM;框架让界面自动随状态变。
- 问题二:什么是”声明式”?答案:你声明”界面基于状态应该长什么样”,而不是一步步命令怎么改 DOM(命令式)。
- 问题三:虚拟 DOM 解决什么?答案:让你用”整体重画”的简单思维,却只付出”局部更新”的性能代价(diff 出差异再更新)。
这一篇你该记住的
- 原生 JS 在大项目里痛在”手动同步 DOM”,数据和界面是两张皮。
- 框架三核心:状态驱动视图、组件化、声明式(而非命令式)。
- 虚拟 DOM 让你”整体重画思维 + 局部更新性能”。
- Vue(平缓、官方一统)vs React(灵活、生态丰富),思想相通,先精通一个。
- 学习顺序:先懂思想 → 再写小组件 → 最后上工程化工具。
下一篇我们讲 Vue 基础:响应式数据、模板语法、常用指令,亲手写出一个能交互的小应用。