Vue(通常读作 "view")是由尤雨溪(Evan You)创建并维护的开源前端 JavaScript 框架,用于构建用户界面和单页面应用。它采用渐进式架构,以声明式渲染和组件化组合为核心,核心库只聚焦视图层,路由、状态管理、构建工具等复杂能力通过官方维护的配套库提供。Vue 基于标准 HTML、CSS 和 JavaScript 构建,以易学易用、性能出色和生态丰富著称,是当前全球应用最广泛的前端框架之一。截至 2026 年 9 月,Vue 3.5 系列为当前稳定版本,Vue 3.6 已进入 RC 阶段并引入 Vapor Mode 与 alien-signals 响应式引擎;Vue 2 已于 2023 年 12 月 31 日停止维护。
Vue 3 的响应式系统基于 ES6 的 Proxy 实现,通过拦截对象操作来追踪数据依赖。当组件渲染函数执行并读取响应式属性时,会触发 Proxy 的 get 拦截器,Vue 借此把当前的渲染副作用(effect)记录为该属性的依赖,这一过程称为依赖收集(track)。当响应式属性被修改时,set 拦截器被触发,Vue 遍历该属性记录的所有依赖并通知它们重新执行,这一过程称为派发更新(trigger)。整个机制可概括为"谁读了我,我就记住谁;我变化时,就通知所有依赖我的人"。
Vue 3 默认采用异步调度策略。同一个事件循环内发生的多次响应式数据变更,会被收集到微任务队列中,在下一次 tick 统一触发组件更新。这种批量更新机制避免了频繁的重渲染,也规避了中间状态被渲染出来的问题,是 Vue 性能表现良好的重要原因。
Vue 2 使用 Object.defineProperty 实现响应式,只能拦截对象属性的 get 和 set,无法检测属性的新增与删除,也无法直接监听数组索引变化,需要重写数组方法加以弥补。Vue 3 改用 Proxy 后可拦截 get、set、delete、has 等 13 种操作,能够检测动态新增属性、数组索引和 length 变化,并原生支持 Map、Set、WeakMap 等集合类型。此外,Proxy 采用惰性代理、按需处理,相比 Vue 2 初始化时递归遍历所有属性,内存开销更低。
Vue 的双向数据绑定指数据变化时视图自动更新,视图变化时数据也同步更新。在数据到视图的方向上,Vue 通过响应式系统监听数据变化,一旦数据改变就自动重新渲染对应的 DOM。开发者无需手动调用 DOM 操作 API,只需关注数据本身。
在视图到数据的方向上,Vue 通过指令和事件机制实现。最典型的是 v-model 指令,它在表单元素和组件上建立双向绑定:输入框的值变化时,绑定的数据自动更新;数据变化时,输入框显示的内容也随之更新。v-model 本质上是 :value(或 :model-value)绑定与 input 事件监听的语法糖。
需要区分双向绑定与组件通信中的单向数据流原则。Vue 组件的 props 遵循单向数据流——父组件向子组件传递数据,子组件不应直接修改 props。当需要子组件向父组件传递变化时,应通过自定义事件通知父组件修改,从而保持数据流向清晰、可追踪。
虚拟 DOM(Virtual DOM)是用轻量 JavaScript 对象模拟真实 DOM 树的结构。每个虚拟节点记录标签名、属性和子节点等信息。当数据变化需要更新视图时,Vue 先在虚拟 DOM 层面对比新旧两棵树的差异(diff),计算出最小变更,再一次性应用到真实 DOM 上,避免频繁、直接的真实 DOM 操作。
Vue 的 diff 算法通过同层比较、key 标识列表项等手段,尽可能复用已有节点,只更新发生变化的部分。在列表渲染中,为每个列表项设置稳定的 key,能帮助 Vue 准确识别哪些项发生了移动、新增或删除,从而做出最优的节点复用与重排,减少不必要的销毁与重建。
Vue 3 的模板编译器在编译阶段做了大量静态分析和优化,例如标记静态节点、识别动态绑定,使运行时的 diff 只需比对真正会变化的动态部分,大幅缩小比较范围。这些编译时优化与虚拟 DOM 的运行时 diff 相结合,共同提升了渲染效率。
Vue 在更新 DOM 时采用异步策略。当响应式数据变化触发组件重新渲染时,Vue 不会立即同步更新 DOM,而是将更新任务放入队列,等到同一事件循环内的数据变化都发生后,再在下一个微任务中统一执行 DOM 更新。这样做可以避免因数据连续变化导致的重复渲染。
nextTick 用于在下次 DOM 更新完成后执行回调。由于 DOM 更新是异步的,当你在修改数据后立即读取 DOM 或依赖更新后的界面状态时,直接访问得到的往往是旧结果。通过 nextTick 注册的回调,会在 Vue 完成 DOM 更新之后运行,从而拿到最新的界面状态。
nextTick 常用于需要在数据变化后操作更新后的 DOM 的场景,例如修改数据后获取元素尺寸、滚动位置,或在第三方图表、富文本库中同步数据后再调用其刷新方法。合理使用 nextTick 能保证回调执行时机与 DOM 更新一致。
响应式系统是 Vue 的核心,负责追踪数据依赖并在数据变化时驱动视图更新。它由 reactive、ref、computed、watch 等 API 构成,底层基于 Proxy 与依赖收集/派发更新机制,是 Vue 声明式编程的基础。
Vue 以组件为基本构建单元,每个组件封装自身的模板、逻辑和样式,通过组合形成复杂的界面。组件系统支持 props 传参、自定义事件、插槽等机制,实现组件间的解耦与复用。
渲染器负责把组件的声明式描述转换为真实 DOM。它基于虚拟 DOM 和 diff 算法,在数据变化时高效地计算并应用最小 DOM 变更。
Vue 的模板编译器负责把模板编译为渲染函数。Vue 3 提供运行时+编译器版本和仅运行时版本,仅运行时版本体积更小,适合对包体积敏感的场景;需要运行时编译(如动态生成模板)时才需引入完整编译器。
Vue 组件是一个包含模板(或渲染函数)、逻辑和样式的可复用单元。单文件组件(.vue 文件)把模板、脚本和样式组织在同一文件中,便于维护。组件可局部注册或全局注册,局部注册仅在引入它的组件内可用,全局注册后可在任意组件中使用。
组件间通过 props 传递数据,子组件通过自定义事件向父组件通知变化,形成单向数据流。跨层级组件可通过 provide/inject 共享数据,避免逐层传递。对于全局共享状态,则推荐使用 Pinia 等状态管理方案统一管理。
Vue 3 的 Composition API 允许把组件逻辑按功能关注点组织,并抽取为可复用的组合式函数(composable)。相比选项式 API 按选项类型分散逻辑,组合式函数能更灵活地在多个组件间共享状态和逻辑,提升大型应用的可维护性。
v-bind(简写为 :)用于动态绑定属性,把表达式结果绑定到元素属性或组件 props 上。v-model 用于在表单元素和组件上建立双向数据绑定。插值表达式 {{ }} 用于在文本节点中输出数据。
v-if、v-else-if、v-else 用于条件渲染,根据表达式的真假决定是否渲染元素;v-show 通过切换 display 属性控制显隐,适用于频繁切换的场景。v-for 用于列表渲染,遍历数组或对象生成多个节点,使用时应为每项设置稳定的 key。
v-on(简写为 @)用于监听 DOM 事件并绑定处理函数。v-html 用于输出经过安全处理的 HTML 内容,使用时需注意防范 XSS 风险。v-once、v-pre、v-cloak 等指令用于渲染优化和编译控制。
除内置指令外,Vue 允许通过 directive 定义自定义指令,在元素的生命周期钩子中执行自定义逻辑,例如点击外部关闭、聚焦、懒加载等场景。
组件从创建到挂载完成依次经历 created、beforeMount、mounted 钩子。created 在组件实例创建后、模板编译前触发,此时可访问数据但无法操作 DOM;beforeMount 在挂载前触发;mounted 在组件挂载到 DOM 后触发,此时可以安全访问和操作 DOM,常用于发起异步请求、初始化第三方库。
当响应式数据变化触发组件重新渲染时,会依次触发 beforeUpdate、updated 钩子。beforeUpdate 在 DOM 更新前触发,updated 在 DOM 更新完成后触发,二者常用于依赖更新后 DOM 状态的操作。
组件从 DOM 移除时触发 beforeUnmount(Vue 3 中为 onBeforeUnmount)和 unmounted(onUnmounted)钩子,常用于清理定时器、事件监听、第三方实例等,避免内存泄漏。
在 Composition API 中,生命周期钩子以函数形式导入使用,如 onMounted、onUpdated、onUnmounted,在 setup 过程中按顺序注册即可,语义与选项式 API 一致。
computed 用于定义计算属性,它基于响应式依赖计算出一个新值,并缓存结果。只有当其依赖发生变化时才会重新计算,否则直接返回缓存值,避免重复运算。计算属性默认只读,也可通过提供 get 和 set 定义可写的计算属性。它适合"根据现有状态推导出新状态"的场景,例如根据列表计算总价、根据姓名拼接全名。
watch 用于监听一个或多个响应式数据源,当数据变化时执行自定义逻辑(副作用),例如发起网络请求、操作路由、修改其他非派生状态。watch 可以获取新旧值,适合在数据变化时执行异步操作或命令式逻辑。
二者的核心区别在于用途:computed 用于声明式地"计算一个值",强调缓存与派生;watch 用于命令式地"在变化时做事",强调副作用执行。能用计算属性表达的派生逻辑优先用 computed,涉及异步、副作用或需要访问新旧值时用 watch。
父组件向子组件通过 props 传递数据,子组件向父组件通过自定义事件(defineEmits)通知变化,这是最基础、最推荐的通信方式,遵循单向数据流原则。v-model 也可用于父子组件间的双向绑定,本质是 props 加事件的语法糖。
对于嵌套较深的组件,逐层传递 props 会繁琐。Vue 提供 provide/inject 机制,祖先组件通过 provide 提供数据,后代组件通过 inject 注入,无需经过中间层级。它适合主题、语言等相对稳定的共享数据,但需注意数据来源的可追踪性。
对于多个组件共享的复杂状态,推荐使用 Pinia 状态管理库。Pinia 提供集中式的 store,任意组件都可读写共享状态,并支持模块化组织和 TypeScript,是大型应用中管理全局状态的官方推荐方案。
在特定场景下,还可通过事件总线、自定义事件或第三方库实现通信,但在 Vue 3 中官方更推荐使用 props/emit、provide/inject 和 Pinia 等规范方式,以保证数据流清晰可维护。
服务端渲染(SSR)指在服务器端把 Vue 组件预渲染为完整的 HTML 字符串再发送给浏览器,浏览器可直接显示内容,无需等待客户端 JavaScript 执行完毕。这能显著改善首屏加载速度和搜索引擎可抓取性。
Vue 核心库支持 SSR,但完整的 SSR 能力通常借助元框架实现。Nuxt 是基于 Vue 的元框架,内置 SSR、静态站点生成(SSG)、文件路由、服务端数据获取等能力,是 Vue 生态中实现 SSR 的主流方案。开发者在 Nuxt 中编写标准 Vue 组件,即可获得服务端渲染能力。
SSR 页面发送到浏览器后,Vue 会在客户端执行"激活"(hydration)过程,把静态 HTML 转换为可交互的应用。激活过程中,Vue 复用服务端生成的 DOM 结构并绑定事件监听,使页面从静态内容变为可响应用户操作的动态界面。
Vue 非常适合构建单页面应用(SPA),通过 Vue Router 实现前端路由,在不刷新整页的情况下切换视图,提供流畅的用户体验,适用于后台管理系统、在线编辑器、数据看板等交互密集型应用。
借助 SSR 或静态站点生成,Vue 可用于构建对首屏速度和 SEO 有要求的内容站点、电商页面和营销落地页,兼顾加载性能与搜索引擎友好性。
由于 Vue 采用渐进式架构,可以按需引入。它既能作为完整框架构建新应用,也能以轻量方式嵌入现有页面,逐步增强交互能力,适合对已有项目进行渐进式改造。
从个人项目到大型企业级应用,Vue 都能胜任。其平缓的学习曲线降低了上手门槛,而 Composition API、TypeScript 支持和丰富的生态又能满足大型应用的工程化需求。
Vue 的响应式系统会为深层对象建立代理。对于不需要响应式的大型静态数据,可使用 shallowRef、shallowReactive 或 markRaw 避免深度代理,减少响应式转换的开销。同时应避免把不需要响应的大对象包裹进响应式系统。
优先用 computed 表达派生状态,利用其缓存特性避免重复计算;对计算成本高的列表,可结合缓存减少重算。避免在模板或计算属性中编写复杂表达式,以免每次渲染都重复执行。
为列表项设置稳定的 key,帮助 diff 算法最大化复用节点。对长列表可使用虚拟滚动等技术只渲染可视区域,减少 DOM 节点数量。
通过路由懒加载和异步组件实现按需加载,把首屏所需代码控制在最小范围。对频繁切换显隐的组件,可结合 keep-alive 缓存组件实例,避免重复创建销毁。
使用 Vite 等现代构建工具,配合生产模式打包、Tree-shaking 移除未使用代码、按需引入第三方库等方式减小包体积。在更新频繁的场景中,可评估使用 Vue 3.6 引入的 Vapor Mode 以获得更优的运行时性能。
Vue 可通过 v-model 双向绑定表单值,并在提交时读取数据执行验证逻辑。验证规则可写在组件方法或组合式函数中,校验结果用于控制错误提示的显示。这种方式灵活,适合结构简单的表单。
借助 watch 或 computed,可在字段值变化时实时执行校验并更新错误状态,实现失焦校验、实时反馈等体验。配合 v-bind 动态切换样式类,可高亮显示校验失败的字段。
对于字段多、规则复杂的表单,可引入成熟的表单验证库(如 VeeValidate 等)来声明式地定义规则、统一处理错误信息,减少重复代码。这类库通常与 Vue 的响应式系统良好集成,能显著提升复杂表单的开发效率和一致性。
在大型单页应用中,把所有页面打包进同一个 bundle 会导致首屏加载缓慢。通过 Vue Router 的动态导入(import() 语法),可以把每个路由对应的组件拆分为独立 chunk,只在访问该路由时才加载对应代码,从而显著减小首屏包体积。
除路由外,对于非首屏必需、体积较大的组件(如富文本编辑器、图表组件),也可使用 defineAsyncComponent 定义为异步组件,在需要渲染时才加载,进一步细化代码分割粒度。
Vite 等构建工具在打包时会自动进行代码分割,将公共依赖、第三方库拆分为可复用的 chunk,并结合浏览器缓存提升二次加载速度。合理配置分割策略,配合路由和组件级懒加载,能有效控制大型应用的加载性能。
Vite 是由 Vue 作者主导开发的新一代前端构建工具。它利用浏览器原生 ES 模块支持,在开发阶段无需预先打包即可按需加载模块,从而实现开发服务器的秒级冷启动,解决了传统打包工具在大型项目中启动缓慢的问题。
Vite 的热模块替换(HMR)基于原生模块,更新时只失效改动的模块及其直接依赖,无需重新构建整个依赖图,因此热更新速度几乎不受项目规模影响,大型应用也能保持即时的热更新体验。
在生产构建阶段,Vite 8 起采用 Rolldown 作为统一的生产打包引擎。Rolldown 是由 VoidZero 团队用 Rust 编写的打包器,兼容 Rollup 的插件 API,相比此前的 Rollup 实现了数量级的构建提速,同时取代了开发阶段的 esbuild,成为覆盖开发与生产全流程的单一打包方案。Vite 与框架无关,除 Vue 外也支持 React、Svelte 等,已成为当前主流的前端构建工具之一。
Vue 是核心框架,聚焦视图层和组件系统;Nuxt 是构建在 Vue 之上的元框架,在 Vue 的基础上补齐了服务端渲染、静态站点生成、文件路由、数据获取、SEO 优化等全栈能力。可以理解为 Vue 提供组件与响应式内核,Nuxt 提供开箱即用的应用级工程方案。
Nuxt 适合需要 SSR 或静态生成、对首屏性能和 SEO 有较高要求的内容型网站、电商、营销页面,以及希望获得约定式路由、自动导入、服务端能力等一体化开发体验的项目。
对于纯客户端交互的单页面应用(如后台管理系统、数据看板),或需要更细粒度控制构建与架构的项目,直接使用 Vue 搭配 Vue Router、Pinia、Vite 等配套库更为灵活。二者并非互斥,团队可根据应用对 SSR、SEO 和工程化程度的需求选择。
Vue 提倡使用模板(template)配合声明式指令描述界面,模板是标准 HTML 的扩展,对新手更直观;React 采用 JSX,用 JavaScript 表达式描述 UI,逻辑与视图在语法上更统一。二者都支持组件化开发,但编写界面时的表达方式不同。
Vue 基于响应式系统,通过 Proxy 追踪依赖,数据变化时自动、精确地更新相关部分,开发者直接修改数据即可;React 采用不可变数据加虚拟 DOM 重渲染的模型,状态更新需通过 setState 或不可变赋值触发,依赖重渲染和 diff 更新界面。这导致二者在性能优化思路上有所不同——Vue 更依赖依赖追踪的精确性,React 更依赖开发者对重渲染的控制(如 memo、依赖数组)。
Vue 提供官方维护的路由(Vue Router)、状态管理(Pinia)、构建工具(Vite)等完整生态,渐进式特性使其可灵活按需引入;React 核心库更聚焦视图,路由、状态管理等大量依赖社区方案,生态更分散但选择也更丰富。
Angular 是由 Google 维护的全功能框架,内置了路由、HTTP、表单、依赖注入等完整能力,采用 TypeScript 优先、基于模块和装饰器的架构,体系严谨但学习曲线较陡。Vue 是渐进式框架,核心库聚焦视图层,其他能力通过可渐进集成的配套库提供,整体更轻量、上手更平缓。
Angular 采用 RxJS 驱动的响应式编程和依赖注入机制,强调以服务和可注入依赖组织应用,适合大型、结构化的企业应用。Vue 采用基于模板和响应式数据的声明式编程,数据流更直观,依赖追踪自动完成,开发心智负担相对较低。
Angular 的强约束和完整工具链适合追求统一架构、团队协作规范严格的大型企业项目;Vue 的渐进式和灵活性适合从中小项目到大型应用的各种场景,尤其在需要快速上手、渐进增强或灵活选型时更具优势。