知用网
霓虹主题四 · 更硬核的阅读氛围

MVVM原理图解:轻松理解数据与视图的自动同步

发布时间:2026-01-23 10:50:54 阅读:167 次

你有没有遇到过这样的情况:在写前端代码时,页面上一个数字要随着用户操作实时变化,于是你一会儿查DOM、一会儿改innerHTML,逻辑一多就乱成一团?其实,这种问题早就有了更优雅的解法——MVVM

MVVM 是什么?

MVVM 全称是 Model-View-ViewModel,它是一种用于构建用户界面的设计模式。名字听起来挺学术,但拆开来看其实很简单:

  • Model:就是数据,比如用户的姓名、购物车里的商品列表。
  • View:就是我们看到的网页界面,HTML + CSS 构成的结构和样式。
  • ViewModel:它是中间的“翻译官”,把数据的变化自动反映到界面上,也把用户的操作反馈回数据。

它怎么工作的?一张图就能说清

想象一下你在用一个记账App,当你点击“收入+100”按钮,页面上的总额立刻变多,根本不用手动去改那个显示数字的标签。这就是 MVVM 在背后干活。

流程大概是这样:

  1. 你点击按钮 → ViewModel 接收到事件
  2. ViewModel 修改 Model 中的 total 值
  3. 由于数据绑定机制,View 自动更新显示

不需要你写 document.getElementById 再 innerText 赋值,一切自动完成。

数据绑定是关键

MVVM 的核心在于“数据绑定”。最常见的是一次性绑定和双向绑定。

比如你有这样一个简单的 ViewModel:

const viewModel = {
  name: '小明',
  age: 24
};

而你的 HTML 长这样:

<div>
  姓名:<span data-bind="text: name"></span>,
  年龄:<span data-bind="text: age"></span>
</div>

当 viewModel.name 变成“小红”时,页面上对应的 span 内容也会跟着变。这是怎么做到的?靠的是监听机制。

监听数据变化:Object.defineProperty 或 Proxy

在 Vue 2 里,用的是 Object.defineProperty 来劫持对象属性的 get 和 set。

let value = '默认值';
Object.defineProperty(viewModel, 'name', {
  get() {
    console.log('有人读取了 name');
    return value;
  },
  set(newValue) {
    console.log('name 被改为', newValue);
    value = newValue;
    // 触发视图更新
    updateView();
  }
});

每次修改 name,set 函数就会被触发,这时候就可以通知页面去刷新对应的部分。

到了 Vue 3,换成了更强大的 Proxy,可以监听整个对象,连新增或删除属性都能捕获。

const proxyVM = new Proxy(viewModel, {
  set(target, key, value) {
    target[key] = value;
    updateView(); // 更新视图
    return true;
  }
});

ViewModel 怎么连接 View?

ViewModel 不直接操作 DOM,而是通过指令或模板语法告诉系统:“这个字段要绑定到哪个位置”。

比如 Vue 中的 {{ }} 插值:

<p>欢迎,{{ name }}!</p>

或者 Angular 中的 [(ngModel)] 实现双向绑定:

<input [(ngModel)]="name" />

输入框内容变了,data 里的 name 也跟着变;反过来,JavaScript 改了 name,输入框也立刻更新。

实际开发中的好处

以前做表单验证,可能得写一堆 if 判断 + getElementById + 提示文案显隐控制。用了 MVVM 后,数据一改,错误提示要不要显示自然就知道了。

比如:

const vm = {
  username: '',
  get showError() {
    return this.username.length < 3 && this.username.length > 0;
  }
};

模板里直接判断是否显示提示:

<div v-if="showError" class="error">用户名至少3位</div>

逻辑清晰,维护起来也省心。

别忘了“响应式”的代价

虽然自动更新很方便,但也不是没有成本。监听越多,内存占用越高,过度使用深层监听可能导致性能下降。所以大列表或高频更新场景下,该用 key 优化还得用,该手动控制更新也别偷懒。

MVVM 不是银弹,但它确实让大多数日常开发变得更轻松了。你现在用的 Vue、React(虽不是严格 MVVM,但思路相近)、Angular,底层都能看到它的影子。