当前位置:首页 > VUE

vue监听实现原理

2026-01-17 19:24:29VUE

Vue 监听实现原理

Vue 的监听机制主要依赖于响应式系统和依赖收集,通过 Object.definePropertyProxy 实现数据劫持,并在数据变化时触发更新。

核心概念:响应式系统

Vue 的响应式系统通过劫持数据的访问和修改,在数据变化时自动更新依赖该数据的视图或计算属性。以下是实现的关键步骤:

  1. 数据劫持
    对于对象属性,Vue 使用 Object.defineProperty(Vue 2)或 Proxy(Vue 3)拦截属性的读取和设置操作。

    • Object.defineProperty 示例:
      Object.defineProperty(obj, key, {
        get() {
          // 依赖收集
          return val
        },
        set(newVal) {
          // 触发更新
          val = newVal
        }
      })
    • Proxy 示例(Vue 3):
      new Proxy(obj, {
        get(target, key) { /* 依赖收集 */ },
        set(target, key, newVal) { /* 触发更新 */ }
      })
  2. 依赖收集
    在属性的 getter 中,Vue 会将当前正在执行的“依赖”(如组件的渲染函数、计算属性等)记录到一个全局的依赖管理器中(如 Dep 类)。

    • 每个属性对应一个 Dep 实例,用于存储所有依赖它的“订阅者”(Watcher 实例)。
    • 当属性被访问时,当前 Watcher 会被添加到 Dep 的订阅列表中。
  3. 触发更新
    当属性被修改时,setter 会通知对应的 Dep 实例,遍历所有订阅的 Watcher 并执行其更新逻辑(如重新渲染组件)。

监听的具体实现

Vue 提供了 watchcomputed 两种监听方式,底层均基于上述响应式系统:

  1. watch 的实现

    • 创建一个 Watcher 实例,传入回调函数和监听的属性路径。
    • 在初始化时,Watcher 会主动触发一次属性的 getter,从而完成依赖收集。
    • 当属性变化时,Watcher 的回调函数会被调用。
  2. computed 的实现

    • 计算属性本质是一个惰性求值的 Watcher,仅在依赖的属性变化时重新计算。
    • 计算属性会缓存结果,避免重复计算。

示例代码解析

以下是一个简化的 WatcherDep 实现:

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 watchEffect(fn) {
  target = fn
  fn() // 触发依赖收集
  target = null
}

const depsMap = new WeakMap()

function reactive(obj) {
  return new Proxy(obj, {
    get(target, key) {
      let dep = depsMap.get(target)
      if (!dep) {
        dep = new Dep()
        depsMap.set(target, dep)
      }
      dep.depend()
      return Reflect.get(target, key)
    },
    set(target, key, newVal) {
      Reflect.set(target, key, newVal)
      const dep = depsMap.get(target)
      if (dep) dep.notify()
      return true
    }
  })
}

总结

Vue 的监听机制通过以下步骤实现:

  • 数据劫持拦截属性的读写操作。
  • 依赖收集在属性访问时记录依赖关系。
  • 触发更新在属性修改时通知所有依赖项。
  • watchcomputed 基于相同的响应式系统,但分别适用于异步回调和高性能计算场景。

vue监听实现原理

标签: 原理vue
分享给朋友:

相关文章

vue实现滚动中断

vue实现滚动中断

Vue 实现滚动中断的方法 在 Vue 中实现滚动中断通常涉及监听滚动事件,并在特定条件下阻止默认行为或停止滚动。以下是几种常见方法: 监听滚动事件并阻止默认行为 通过 @scroll 或 @wh…

vue实现安全免登录

vue实现安全免登录

Vue 实现安全免登录的方案 免登录功能通常通过持久化认证状态(如 Token)实现,但需兼顾安全性。以下是基于 Vue 的常见实现方案: 基于 Token 的免登录 登录成功后存储 Token…

vue实现生成二维码

vue实现生成二维码

使用qrcode.vue库生成二维码 安装qrcode.vue库: npm install qrcode.vue --save 在Vue组件中使用: <template> &l…

vue筛选实现

vue筛选实现

Vue 筛选实现方法 使用计算属性实现筛选 计算属性是 Vue 中实现数据筛选的常用方式。通过定义一个计算属性,可以根据输入的条件动态过滤数据。 <template> <div…

vue 全景实现

vue 全景实现

Vue 全景实现方案 在Vue中实现全景效果,通常需要结合WebGL或第三方库来处理3D场景渲染。以下是几种常见方法: 使用Three.js库 Three.js是一个强大的WebGL库,适合创建…

javascript实现vue

javascript实现vue

Vue.js 的基本实现 在 JavaScript 中实现 Vue.js 的核心功能,主要包括数据绑定、响应式系统和虚拟 DOM。以下是一个简化的实现示例。 数据响应式系统 通过 Object.d…