Vue 是如何实现 MVVM 的?

95 阅读3分钟

Vue.js 通过其精巧的响应式系统,优雅地实现了 MVVM(Model-View-ViewModel)模式。简单来说,它构建了一个自动化桥梁,让数据(Model)和界面(View)能够无缝同步。下面这张图清晰地展示了其核心的工作流程:

image.png

flowchart TD
    A[Model<br>数据层] --> B{ViewModel<br>响应式系统}
    B --> C[View<br>视图层/模板]
    C -- 用户交互/指令 --> D[Compile<br>模板编译]
    D --> E[Watcher<br>依赖追踪]
    E --> F[Getter<br>依赖收集]
    F --> A
    A -- 数据变化 --> G[Setter<br>触发通知]
    G --> H[Dep<br>依赖管理器]
    H --> I[Watcher<br>更新视图]
    I --> C

下面我们来详细解读图中的每一个关键部分。

🔧 核心机制解析

Vue 的 MVVM 实现主要依赖于以下几个核心部件,它们各司其职,协同工作:

  1. ​响应式数据层(Model → ViewModel)​​ Vue 使用 ​​数据劫持​​ 来使普通 JavaScript 对象变成响应式的。在 Vue 2 中,这是通过 Object.defineProperty实现的;而在 Vue 3 中,则升级为功能更强大的 Proxy。这个过程会为每个响应式属性创建一个 ​​依赖管理器(Dep)​​。当组件渲染时,任何对响应式数据的访问都会触发属性的 getter,此时 Vue 会将当前的 ​​渲染 Watcher​​ 收集到该属性的 Dep 中,建立依赖关系。当数据发生变化时,setter会被触发,Dep 会通知所有关联的 Watcher 进行更新 。
  2. ​模板编译(View → ViewModel)​​ Vue 的编译器会将你编写的 HTML-like 模板编译成 ​​渲染函数(render function)​​。在这个过程中,编译器会解析模板中的指令(如 v-model, {{ }}插值),并识别出哪些数据被引用了。然后,它为每个需要动态更新的部分创建对应的 ​​Watcher​​。这些 Watcher 就是视图对数据的“订阅者” 。
  3. ​虚拟DOM与差异更新(ViewModel → View)​​ 当数据变化触发 Watcher 更新时,Vue 并不会直接操作真实 DOM。而是会先执行渲染函数,生成一个新的 ​​虚拟 DOM 树(Virtual DOM)​​,它是一个轻量级的 JavaScript 对象,描述了页面的结构。随后,Vue 会将新的虚拟 DOM 与上一次渲染的旧虚拟 DOM 进行对比(这个过程叫做 ​​Diff​​),精确找出需要变更的最小单位。最后,只将差异部分应用到真实 DOM 上,从而高效地更新视图 。

⚙️ 关键角色与流程对应

  • ​Model​​:就是你的数据对象,例如 Vue 组件中的 data函数返回的对象 。
  • ​View​​:即你的模板,最终渲染成的用户界面 。
  • ​ViewModel​​:这是 Vue 实例本身,它作为核心枢纽,通过响应式系统、编译器和虚拟DOM等机制,协调 Model 和 View 之间的自动同步 。

💡 举例说明 v-model的双向绑定

v-model指令为例,它是双向绑定最直观的体现:

<input type="text" v-model="message">
<p>{{ message }}</p>
  1. ​数据 -> 视图(Model -> View)​​:初始化时,message的值通过数据劫持和依赖收集,被显示在 input的输入框和 p标签中。
  2. ​视图 -> 数据(View -> Model)​​:当用户在输入框中输入内容时,input事件会触发。Vue 为 v-model指令生成的逻辑会自动将输入的新值赋给 message属性。
  3. ​数据变更,视图同步更新​​:当 message被修改,setter 被触发,所有依赖于此数据的 Watcher(包括那个 p标签的 Watcher)会被通知更新,从而同步更新 p标签内的文本内容 。

💎 总结

Vue 实现 MVVM 的核心在于建立一个​​自动化的响应机制​​。它通过​​数据劫持​​来观察数据变化,通过​​依赖收集​​来建立数据和视图的关联,再通过​​虚拟DOM差异更新​​来高效地将变化反映到界面上。这套机制让开发者可以从繁琐的 DOM 操作中解放出来,只需关心数据状态,极大地提升了开发效率和体验 。 希望这个解释能帮助你清晰地理解 Vue 的 MVVM 实现原理。