当前位置:首页 > 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中实现注册功能通常需要结合前端表单和后端API交互。以下是完整的实现方案: 创建注册表单组件 注册表单需要包含用户名、邮箱、密码等基本字段,并进行表单验证: <te…

前端vue登录功能实现

前端vue登录功能实现

Vue 登录功能实现步骤 创建登录表单组件 在 Vue 项目中创建一个登录组件,通常命名为 Login.vue。该组件包含用户名和密码输入框以及提交按钮。 <template> &l…

vue查看更多怎么实现

vue查看更多怎么实现

实现 Vue 的“查看更多”功能 数据截取与显示控制 通过 v-if 或 v-show 控制内容的显示与隐藏。初始状态下只显示部分内容,点击“查看更多”后展开完整内容。 <template&…

vue实现防抖节流

vue实现防抖节流

Vue 中实现防抖(Debounce) 防抖的核心是延迟执行函数,在连续触发时取消前一次的调用,只执行最后一次。适用于输入框搜索、窗口大小调整等场景。 方法1:使用 Lodash 的 _.debo…

vue设计与实现目录

vue设计与实现目录

以下是《Vue设计与实现》一书的典型目录结构(根据常见技术书籍及Vue核心内容整理): 响应式系统 响应式数据的基本原理 依赖收集与触发更新 实现简易响应式系统 Proxy与Reflec…

vue实现冰墩墩

vue实现冰墩墩

使用 Vue 实现冰墩墩动画 通过 Vue 的动画特性和 SVG 技术,可以动态渲染冰墩墩的形象。以下是具体实现方法: 准备 SVG 素材 冰墩墩的形象通常由多个 SVG 路径组成,包括身体轮廓、面…