当前位置:首页 > VUE

vue数据驱动模拟实现

2026-01-23 13:09:29VUE

Vue 数据驱动模拟实现

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

响应式数据劫持

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

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表单搜索功能 在Vue中实现表单搜索功能通常涉及表单绑定、事件处理和搜索逻辑。以下是具体实现方法: 数据绑定与表单结构 使用v-model实现表单与Vue数据的双向绑定: <tem…

vue实现文字播放栏

vue实现文字播放栏

Vue 实现文字播放栏(跑马灯效果) 方法一:使用 CSS 动画 + Vue 数据绑定 通过 CSS 的 @keyframes 实现动画效果,结合 Vue 的动态数据绑定控制内容。 <tem…

vue怎么实现文件树

vue怎么实现文件树

Vue 实现文件树的方法 使用递归组件 递归组件是处理嵌套数据结构的理想方式。文件树通常包含文件夹和文件的嵌套结构,适合用递归组件实现。 <template> <ul>…

vue实现按卡片轮播

vue实现按卡片轮播

实现卡片轮播的基本思路 在Vue中实现卡片轮播可以通过结合v-for指令和动态样式绑定完成。核心是维护一个当前显示卡片的索引,通过CSS过渡效果实现平滑切换。 基础实现步骤 模板部分 使用v-for…

vue的艾特功能实现

vue的艾特功能实现

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

vue  select实现

vue select实现

Vue Select 实现方法 在 Vue 中实现下拉选择功能可以使用原生 <select> 标签或第三方库如 vue-select。以下是两种方法的详细说明: 原生 HTML Sele…