当前位置:首页 > VUE

vue数据驱动模拟实现

2026-01-23 13:09:29VUE

Vue 数据驱动模拟实现

Vue 的数据驱动核心基于响应式系统,通过劫持数据变化触发视图更新。以下是模拟实现的关键步骤:

vue数据驱动模拟实现

响应式数据劫持

使用 Object.definePropertyProxy 监听对象属性变化:

vue数据驱动模拟实现

function defineReactive(obj, key, val) {
  const dep = new Dep(); // 依赖收集器
  Object.defineProperty(obj, key, {
    get() {
      Dep.target && dep.addSub(Dep.target); // 收集依赖
      return val;
    },
    set(newVal) {
      if (newVal === val) return;
      val = newVal;
      dep.notify(); // 触发更新
    }
  });
}

依赖收集与派发更新

实现 Dep(依赖管理器)和 Watcher(观察者):

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

class Watcher {
  constructor(vm, key, cb) {
    Dep.target = this;
    this.vm = vm;
    this.key = key;
    this.cb = cb;
    this.value = vm[key]; // 触发 getter 收集依赖
    Dep.target = null;
  }
  update() {
    const newValue = this.vm[this.key];
    if (newValue !== this.value) {
      this.cb(newValue);
      this.value = newValue;
    }
  }
}

模板编译与绑定

模拟 compile 解析模板并绑定数据:

function compile(el, vm) {
  const fragment = document.createDocumentFragment();
  let child;
  while ((child = el.firstChild)) {
    fragment.appendChild(child);
  }

  const nodes = fragment.querySelectorAll('[v-model]');
  nodes.forEach(node => {
    const key = node.getAttribute('v-model');
    new Watcher(vm, key, value => {
      node.value = value;
    });
    node.addEventListener('input', e => {
      vm[key] = e.target.value;
    });
  });

  el.appendChild(fragment);
}

完整示例整合

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

  observe(data) {
    Object.keys(data).forEach(key => {
      defineReactive(this, key, data[key]);
    });
  }
}

使用示例

<div id="app">
  <input v-model="message" />
  <p>{{ message }}</p>
</div>

<script>
  const vm = new MiniVue({
    el: '#app',
    data: { message: 'Hello Vue' }
  });
</script>

关键点说明

  • 数据劫持:通过拦截对象的读写操作实现响应式。
  • 依赖收集:在 getter 中收集依赖,在 setter 中触发更新。
  • 异步更新队列:实际 Vue 会使用队列优化多次更新(此处简化实现)。
  • 虚拟 DOM 差异:完整版 Vue 会结合虚拟 DOM 提升性能,模拟实现可省略此步骤。

标签: 数据vue
分享给朋友:

相关文章

vue为啥能实现监听

vue为啥能实现监听

Vue 实现监听的原理 Vue 的监听能力主要基于其响应式系统,该系统通过数据劫持和依赖收集实现。当数据变化时,系统能自动触发视图更新或执行回调函数。 核心机制:Object.definePrope…

vue实现拖放

vue实现拖放

Vue 实现拖放功能 Vue 中实现拖放功能通常可以通过 HTML5 的原生拖放 API 或第三方库(如 vuedraggable)来实现。以下是两种方法的详细说明。 使用 HTML5 原生拖放 A…

vue的实现

vue的实现

Vue 的实现原理 Vue 是一个渐进式 JavaScript 框架,其核心实现主要包括响应式系统、虚拟 DOM、模板编译和组件化机制。以下是 Vue 实现的主要技术细节。 响应式系统 Vue 的响…

vue实现frame

vue实现frame

Vue 中实现 iframe 的方法 在 Vue 中可以通过直接使用 <iframe> 标签或动态绑定 src 属性来实现 iframe 功能。 基本用法 <template&g…

实现vue框架

实现vue框架

Vue框架的基本实现 Vue是一个渐进式JavaScript框架,用于构建用户界面。以下是实现Vue框架的基本步骤: 安装Vue 通过CDN引入Vue是最简单的方式: <script src…

vue键盘实现

vue键盘实现

监听键盘事件 在Vue中监听键盘事件可以通过v-on指令或@缩写实现。常见的键盘事件包括keydown、keyup和keypress。例如监听回车键事件: <template> &l…