当前位置:首页 > 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 实现:

vue 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请求实现进度条

实现请求进度条的方法 在Vue中实现请求进度条可以通过多种方式完成,常见的有使用第三方库如axios结合nprogress或自定义进度条组件。以下是几种实现方法: 使用axios和nprogress…

vue scrolltop 实现

vue scrolltop 实现

实现 Vue 中的 scrollTop 在 Vue 中实现滚动到顶部功能可以通过多种方式完成,包括使用原生 JavaScript、Vue 指令或第三方库。以下是几种常见的实现方法: 使用原生 Jav…

mvvm实现vue

mvvm实现vue

MVVM 模式在 Vue 中的实现 MVVM(Model-View-ViewModel)是一种前端架构模式,Vue 的设计灵感来源于此。以下是 MVVM 在 Vue 中的核心实现方式: 数据绑定(M…

vue实现列表

vue实现列表

Vue 实现列表的方法 在 Vue 中实现列表渲染通常使用 v-for 指令,可以动态生成多个元素。以下是几种常见的实现方式: 基础列表渲染 使用 v-for 遍历数组,生成列表项。v-for 需要…

vue实现上划

vue实现上划

Vue 实现上划功能 在Vue中实现上划功能,可以通过监听触摸事件(touchstart、touchmove、touchend)来判断用户的手势方向。以下是实现上划功能的几种方法: 监听触摸事件 通…

vue路由实现iframe

vue路由实现iframe

在Vue中实现iframe嵌入可以通过路由配置和组件动态加载来完成。以下是具体实现方法: 路由配置 在Vue Router的路由配置中,通过component属性动态加载iframe组件。需要将目标…