当前位置:首页 > VUE

vue mvvm实现

2026-01-13 00:42:53VUE

Vue 的 MVVM 实现原理

Vue 是一个基于 MVVM(Model-View-ViewModel)设计模式的前端框架,通过数据绑定和响应式系统实现视图与数据的自动同步。以下是 Vue 实现 MVVM 的核心机制:

数据劫持与响应式系统

Vue 使用 Object.defineProperty(Vue 2)或 Proxy(Vue 3)对数据进行劫持,监听数据变化。当数据被修改时,触发依赖更新。

vue mvvm实现

// Vue 2 的数据劫持示例
const data = { name: 'Vue' };
Object.defineProperty(data, 'name', {
  get() {
    console.log('获取数据');
    return this._name;
  },
  set(newVal) {
    console.log('更新数据');
    this._name = newVal;
    // 触发视图更新
  }
});

依赖收集与观察者模式

Vue 通过 Dep(依赖管理器)和 Watcher(观察者)实现依赖收集。每个响应式属性都有一个 Dep 实例,用于存储依赖该属性的 Watcher

class Dep {
  constructor() {
    this.subscribers = [];
  }
  depend() {
    if (target && !this.subscribers.includes(target)) {
      this.subscribers.push(target);
    }
  }
  notify() {
    this.subscribers.forEach(sub => sub());
  }
}

模板编译与虚拟 DOM

Vue 将模板编译为渲染函数,生成虚拟 DOM(VNode)。通过 diff 算法对比新旧 VNode,高效更新真实 DOM。

vue mvvm实现

// 示例:模板编译为渲染函数
const template = '<div>{{ name }}</div>';
const render = new Function('with(this){return _c("div",[_v(_s(name))])}');

双向数据绑定

通过 v-model 指令实现双向绑定,本质是语法糖:

  • value 属性绑定到数据(Model → View)。
  • 监听 input 事件更新数据(View → Model)。
<input v-model="message">
<!-- 等价于 -->
<input :value="message" @input="message = $event.target.value">

实现简易 MVVM 示例

以下是一个简化版的 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.depend();
          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') {
            node.value = this.$data[attr.value];
            node.addEventListener('input', e => {
              this.$data[attr.value] = e.target.value;
            });
          }
        }
      });
    }
    if (node.childNodes) {
      node.childNodes.forEach(child => this.compileNode(child));
    }
  }
}

关键点总结

  • 数据劫持:通过 Object.definePropertyProxy 监听数据变化。
  • 依赖收集:在 getter 中收集依赖,在 setter 中触发更新。
  • 批量异步更新:通过队列机制优化多次数据变更的渲染性能。
  • 虚拟 DOM:减少直接操作 DOM 的开销,提升性能。

标签: vuemvvm
分享给朋友:

相关文章

vue实现选区创建

vue实现选区创建

Vue 实现选区创建的方法 在 Vue 中实现选区创建通常涉及 DOM 操作和事件处理。以下是几种常见的方法: 使用原生 DOM API 通过 window.getSelection() 和 Ra…

vue怎么实现动画

vue怎么实现动画

Vue 动画实现方法 Vue 提供了多种方式实现动画效果,包括内置过渡系统、第三方库集成以及 CSS 动画。以下是常见实现方法: 使用 Vue 过渡系统 通过 <transition>…

vue实现列表显示

vue实现列表显示

Vue 实现列表显示的方法 在 Vue 中实现列表显示通常使用 v-for 指令,结合数组或对象数据渲染动态列表。以下是几种常见的实现方式。 基本列表渲染 通过 v-for 指令遍历数组,动态生成列…

vue状态管理怎么实现

vue状态管理怎么实现

Vue 状态管理实现方法 使用 Vuex(官方推荐) Vuex 是 Vue 的官方状态管理库,适合中大型应用。 安装 Vuex: npm install vuex --save 创建 Store 示…

vue实现走势图

vue实现走势图

Vue 实现走势图的方法 使用 ECharts 库 ECharts 是一个强大的数据可视化库,支持多种图表类型,包括走势图(折线图)。在 Vue 项目中可以通过 vue-echarts 封装库或直接使…

vue的艾特功能实现

vue的艾特功能实现

Vue 的 @ 功能实现 在 Vue 中实现类似社交平台的 @ 功能,通常涉及输入框的监听、用户匹配和选择插入。以下是具体实现方法: 监听输入框内容 使用 v-model 绑定输入框内容,并通过…