当前位置:首页 > VUE

vue双向绑定实现函数

2026-02-24 04:55:07VUE

Vue 双向绑定实现原理

Vue 的双向绑定是通过数据劫持结合发布者-订阅者模式实现的,核心是 Object.defineProperty(Vue 2.x)或 Proxy(Vue 3.x)。

基于 Object.defineProperty 的实现(Vue 2.x)

  1. 数据劫持 通过 Object.defineProperty 劫持对象的属性,在属性被访问或修改时触发 getter 和 setter。

    function defineReactive(obj, key, val) {
      Object.defineProperty(obj, key, {
        get() {
          console.log(`获取 ${key}: ${val}`);
          return val;
        },
        set(newVal) {
          if (newVal !== val) {
            console.log(`设置 ${key}: ${newVal}`);
            val = newVal;
          }
        }
      });
    }
  2. 依赖收集 在 getter 中收集依赖(订阅者),在 setter 中通知依赖更新。

    class Dep {
      constructor() {
        this.subscribers = [];
      }
      depend() {
        if (target && !this.subscribers.includes(target)) {
          this.subscribers.push(target);
        }
      }
      notify() {
        this.subscribers.forEach(sub => sub());
      }
    }
    
    let target = null;
    function defineReactive(obj, key, val) {
      const dep = new Dep();
      Object.defineProperty(obj, key, {
        get() {
          dep.depend();
          return val;
        },
        set(newVal) {
          if (newVal !== val) {
            val = newVal;
            dep.notify();
          }
        }
      });
    }
  3. 观察者 创建一个观察者函数,用于更新视图。

    function watcher(fn) {
      target = fn;
      fn();
      target = null;
    }
  4. 完整示例

    vue双向绑定实现函数

    const data = { text: 'hello' };
    defineReactive(data, 'text', data.text);
    watcher(() => {
      console.log('视图更新:', data.text);
    });
    data.text = 'world'; // 触发视图更新

基于 Proxy 的实现(Vue 3.x)

Vue 3.x 使用 Proxy 替代 Object.defineProperty,解决了无法监听数组变化和对象新增属性的问题。

  1. Proxy 数据劫持

    function reactive(obj) {
      const handler = {
        get(target, key, receiver) {
          track(target, key);
          return Reflect.get(target, key, receiver);
        },
        set(target, key, value, receiver) {
          Reflect.set(target, key, value, receiver);
          trigger(target, key);
          return true;
        }
      };
      return new Proxy(obj, handler);
    }
  2. 依赖收集与触发

    vue双向绑定实现函数

    const targetMap = new WeakMap();
    function track(target, key) {
      if (!activeEffect) return;
      let depsMap = targetMap.get(target);
      if (!depsMap) {
        targetMap.set(target, (depsMap = new Map()));
      }
      let dep = depsMap.get(key);
      if (!dep) {
        depsMap.set(key, (dep = new Set()));
      }
      dep.add(activeEffect);
    }
    
    function trigger(target, key) {
      const depsMap = targetMap.get(target);
      if (!depsMap) return;
      const dep = depsMap.get(key);
      if (dep) {
        dep.forEach(effect => effect());
      }
    }
    
    let activeEffect = null;
    function effect(fn) {
      activeEffect = fn;
      fn();
      activeEffect = null;
    }
  3. 完整示例

    const data = reactive({ text: 'hello' });
    effect(() => {
      console.log('视图更新:', data.text);
    });
    data.text = 'world'; // 触发视图更新

双向绑定的实现

双向绑定通常用于表单输入,结合 v-model 指令实现。

  1. 模板编译 将模板中的 v-model 解析为事件监听和属性绑定。

    <input v-model="message" />
    <!-- 等价于 -->
    <input :value="message" @input="message = $event.target.value" />
  2. 手动实现双向绑定

    function bindInput(data, key, input) {
      input.value = data[key];
      input.addEventListener('input', (e) => {
        data[key] = e.target.value;
      });
    }
    
    const data = reactive({ message: '' });
    const input = document.querySelector('input');
    bindInput(data, 'message', input);
    effect(() => {
      console.log('数据更新:', data.message);
    });

总结

  • Vue 2.x 使用 Object.defineProperty 实现数据劫持,需要递归遍历对象属性。
  • Vue 3.x 使用 Proxy 实现数据劫持,能监听数组和对象新增属性。
  • 双向绑定是数据劫持与事件监听的结合,通过 v-model 简化操作。

标签: 绑定双向
分享给朋友:

相关文章

怎么用vue.js实现双向绑定

怎么用vue.js实现双向绑定

使用 v-model 指令实现双向绑定 Vue.js 提供了 v-model 指令用于在表单输入元素(如 input、textarea、select)上实现双向数据绑定。v-model 会根据控件类型…

vue 实现循环绑定

vue 实现循环绑定

Vue 实现循环绑定的方法 在 Vue 中,可以通过 v-for 指令实现循环绑定,用于渲染列表或对象数据。以下是几种常见的实现方式: 数组循环绑定 使用 v-for 遍历数组,可以通过索引或直接获…

vue实现数组绑定

vue实现数组绑定

Vue 数组绑定的实现方法 Vue 提供了多种方式实现数组的响应式绑定,确保数据变化时视图自动更新。以下是常见的实现方法: 使用 v-for 指令渲染数组 通过 v-for 指令可以遍历数组并渲染…

vue 双向实现原理

vue 双向实现原理

Vue 双向绑定的实现原理 Vue 的双向绑定主要通过 v-model 指令实现,其核心是结合数据劫持(Object.defineProperty 或 Proxy)和发布-订阅模式。以下是具体实现机制…

实现vue动态绑定

实现vue动态绑定

动态绑定的基本语法 在Vue中,使用v-bind指令或简写:实现动态绑定,将数据属性与HTML元素的属性关联起来。例如动态绑定class或style: <div v-bind:class="{…

vue实现双休绑定

vue实现双休绑定

Vue 实现双向绑定 Vue.js 通过 v-model 指令实现双向绑定,主要用于表单输入元素(如 <input>、<textarea>、<select>)与组件…