当前位置:首页 > 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 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 操作。

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,解决了数组监听和对象新增属性的限制,同时优化了性能。

vue mvvm实现

标签: vuemvvm
分享给朋友:

相关文章

vue中如何实现循环

vue中如何实现循环

在 Vue 中实现循环 Vue 提供了 v-for 指令用于实现循环渲染列表数据。v-for 可以遍历数组、对象或数字范围,生成动态的 DOM 元素。 遍历数组 使用 v-for 遍历数组时,语法…

django vue实现

django vue实现

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

vue 实现闪烁

vue 实现闪烁

Vue 实现闪烁效果的方法 方法一:使用 CSS 动画 在 Vue 组件中定义一个闪烁的 CSS 动画,通过绑定 class 或 style 来控制元素的闪烁效果。 <template>…

vue实现active

vue实现active

Vue 实现 active 状态的方法 在 Vue 中实现 active 状态可以通过以下几种方式实现,具体取决于使用场景和需求。 使用 v-bind:class 动态绑定类名 通过 v-bind:…

vue实现水印

vue实现水印

Vue 实现水印的方法 使用 CSS 背景图 通过 CSS 的 background-image 和 background-repeat 属性实现水印效果。创建一个包含水印文本的 Canvas,将其转…

vue实现fullpage

vue实现fullpage

Vue 实现 FullPage 效果 在 Vue 中实现全屏滚动(FullPage)效果可以通过多种方式完成,以下是几种常见的方法: 使用现有库 vue-fullpage.js 安装 vue-ful…