当前位置:首页 > VUE

vue mvvm实现

2026-02-10 08:01:03VUE

Vue 的 MVVM 实现原理

Vue 的 MVVM(Model-View-ViewModel)模式通过数据绑定和响应式系统实现视图与数据的自动同步。以下是其核心实现机制:

数据劫持与响应式

Vue 使用 Object.defineProperty(Vue 2)或 Proxy(Vue 3)劫持数据对象的属性访问和修改。当数据变化时,触发依赖更新。

vue mvvm实现

// Vue 2 数据劫持示例
function defineReactive(obj, key, val) {
  Object.defineProperty(obj, key, {
    get() {
      console.log('读取数据');
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      console.log('更新数据');
      val = newVal;
      // 触发视图更新
    }
  });
}

依赖收集与观察者模式

每个响应式属性关联一个 Dep(依赖收集器),在 getter 中收集依赖(Watcher),在 setter 中通知依赖更新。

class Dep {
  constructor() {
    this.subs = [];
  }
  addSub(sub) {
    this.subs.push(sub);
  }
  notify() {
    this.subs.forEach(sub => sub.update());
  }
}

class Watcher {
  update() {
    // 更新视图
  }
}

虚拟 DOM 与差异更新

Vue 将模板编译为虚拟 DOM(VNode),通过 diff 算法对比新旧 VNode,最小化 DOM 操作。

vue mvvm实现

function patch(oldVnode, newVnode) {
  // 对比节点差异并更新真实 DOM
}

模板编译

Vue 将模板转换为渲染函数,解析指令(如 v-model)并生成绑定代码。

// v-model 双向绑定实现
<input v-model="message" />
// 编译为:
<input :value="message" @input="message = $event.target.value" />

双向绑定实现示例

以下是一个简化的 MVVM 实现:

class Vue {
  constructor(options) {
    this.$data = options.data;
    this.observe(this.$data);
    this.compile(options.el);
  }

  observe(data) {
    Object.keys(data).forEach(key => {
      let value = data[key];
      const dep = new Dep();
      Object.defineProperty(data, key, {
        get() {
          if (Dep.target) dep.addSub(Dep.target);
          return value;
        },
        set(newVal) {
          value = newVal;
          dep.notify();
        }
      });
    });
  }

  compile(el) {
    const element = document.querySelector(el);
    this.compileNode(element);
  }

  compileNode(node) {
    if (node.nodeType === 1) { // 元素节点
      Array.from(node.attributes).forEach(attr => {
        if (attr.name.startsWith('v-')) {
          const dir = attr.name.substring(2);
          if (dir === 'model') {
            new Watcher(this.$data, attr.value, (val) => {
              node.value = val;
            });
            node.addEventListener('input', (e) => {
              this.$data[attr.value] = e.target.value;
            });
          }
        }
      });
    }
  }
}

关键点总结

  • 数据劫持:通过拦截对象属性的读写操作实现响应式。
  • 依赖收集:在属性读取时收集依赖,在修改时通知更新。
  • 批量异步更新:通过队列机制优化多次数据变更的渲染性能。
  • 虚拟 DOM:减少直接操作真实 DOM 的开销。

Vue 3 改用 Proxy 替代 Object.defineProperty,解决了数组监听和对象新增属性的限制,同时优化了性能。

标签: vuemvvm
分享给朋友:

相关文章

vue实现打印二维码

vue实现打印二维码

安装二维码生成库 使用 qrcode 或 vue-qrcode 库生成二维码。通过 npm 安装: npm install qrcode vue-qrcode 生成二维码 在 Vue 组件中引入…

vue实现弹窗

vue实现弹窗

Vue 实现弹窗的常见方法 使用组件化方式封装弹窗 创建一个独立的弹窗组件(如 Modal.vue),通过 v-if 或 v-show 控制显示隐藏: <template> <…

vue聊天实现

vue聊天实现

Vue 聊天应用实现步骤 创建 Vue 项目 使用 Vue CLI 或 Vite 初始化项目,安装必要依赖(如 Vue 3、Element UI 或 Vuetify 用于 UI 组件)。 npm c…

vue 实现弹幕

vue 实现弹幕

vue 实现弹幕的方法 使用 CSS 动画和动态渲染 在 Vue 中实现弹幕效果,可以通过动态渲染弹幕元素并结合 CSS 动画实现。以下是具体步骤: 数据准备 创建一个数组存储弹幕数据,每条弹幕包…

vue 实现拖拽

vue 实现拖拽

Vue 实现拖拽功能 使用 HTML5 原生拖拽 API HTML5 提供了原生的拖拽 API,可以通过 draggable 属性和相关事件实现拖拽功能。 <template> &l…

django vue实现

django vue实现

Django与Vue.js整合实现方案 Django作为后端框架与Vue.js作为前端框架的整合,可以通过以下方式实现: 分离式开发 前后端完全分离,Django仅提供API接口,Vue.js通过a…