当前位置:首页 > VUE

vue双向实现

2026-01-11 21:37:32VUE

Vue 双向绑定的实现原理

Vue 的双向绑定主要通过 v-model 指令实现,底层结合了数据劫持(Object.definePropertyProxy)和发布-订阅模式。以下是核心实现机制:

数据劫持

Vue 2.x 使用 Object.defineProperty 劫持对象的属性访问和修改,Vue 3.x 改用 Proxy 实现更高效的数据监听。

Vue 2.x 示例:

const data = { text: '' };
Object.defineProperty(data, 'text', {
  get() {
    return this._text;
  },
  set(newVal) {
    this._text = newVal;
    console.log('数据更新了');
  }
});

Vue 3.x 示例:

const data = { text: '' };
const proxy = new Proxy(data, {
  get(target, key) {
    return target[key];
  },
  set(target, key, value) {
    target[key] = value;
    console.log('数据更新了');
    return true;
  }
});

发布-订阅模式

通过 Dep(依赖收集器)和 Watcher(观察者)实现数据变化时的视图更新:

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

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

v-model 的实现

v-model 是语法糖,本质上是 :value@input 的组合:

<input v-model="text">
<!-- 等价于 -->
<input :value="text" @input="text = $event.target.value">

自定义双向绑定组件

通过 model 选项和 $emit 实现自定义组件的双向绑定:

子组件:

export default {
  model: {
    prop: 'value',
    event: 'change'
  },
  props: ['value'],
  methods: {
    handleInput(e) {
      this.$emit('change', e.target.value);
    }
  }
}

父组件使用:

vue双向实现

<custom-input v-model="text"></custom-input>

注意事项

  • Vue 2.x 中 Object.defineProperty 无法检测数组下标变化,需通过 Vue.set 或数组方法触发更新。
  • Vue 3.x 的 Proxy 支持深层监听,但需注意性能开销。
  • 复杂场景可结合 .sync 修饰符或 v-bind.sync 实现多属性双向绑定。

标签: 双向vue
分享给朋友:

相关文章

vue懒加载实现难吗

vue懒加载实现难吗

vue懒加载的实现难度 Vue懒加载的实现并不复杂,核心逻辑是通过动态导入(Dynamic Imports)和路由配置或组件异步加载完成。以下是具体实现方法: 路由懒加载实现 在Vue Router…

代码实现vue

代码实现vue

创建Vue项目 使用Vue CLI快速初始化项目,确保已安装Node.js和npm/yarn: npm install -g @vue/cli vue create my-vue-project c…

vue实现拍照

vue实现拍照

Vue实现拍照功能 在Vue中实现拍照功能通常需要结合浏览器的MediaDevices API和Canvas元素。以下是具体实现方法: 安装依赖(可选) 如果需要更简单的封装,可以安装vue-web…

vue实现handsontable

vue实现handsontable

Vue 中实现 Handsontable 要在 Vue 项目中集成 Handsontable,可以使用官方提供的 @handsontable/vue 封装库。以下是一个完整的实现步骤。 安装依赖 确…

vue实现分发

vue实现分发

Vue 实现分发的方法 在 Vue 中,分发(Distribution)通常指的是将内容从父组件传递到子组件,或者通过插槽(Slots)机制让父组件控制子组件的部分渲染内容。以下是几种常见的实现分发的…

vue实现拖动

vue实现拖动

Vue实现拖动的常用方法 在Vue中实现拖动功能通常需要结合HTML5的拖放API或第三方库。以下是几种常见实现方式: 使用HTML5原生拖放API HTML5提供了原生拖放API,可以通过drag…