当前位置:首页 > VUE

vue实现依赖收集

2026-02-11 05:21:21VUE

Vue 依赖收集实现原理

Vue 的依赖收集机制基于响应式系统,核心是通过 Object.definePropertyProxy 拦截数据访问,在 getter 中收集依赖,在 setter 中触发更新。

核心实现步骤

初始化阶段

  • 通过 Observer 类将数据对象转换为响应式对象,遍历对象的每个属性,使用 Object.defineProperty 定义 getter/setter。
  • 每个响应式属性会关联一个 Dep 实例(依赖收集器),用于存储所有依赖该属性的 Watcher

依赖收集过程

  • 当组件渲染或计算属性计算时,会创建一个 Watcher 实例。
  • Watcher 在求值前会调用 pushTarget 方法,将自身设置为当前活跃的 Watcher
  • 访问响应式数据时触发 getter,getter 中调用 dep.depend(),将当前活跃的 Watcher 添加到 Dep 的订阅列表中。
  • 完成求值后,Watcher 通过 popTarget 移除当前活跃状态。

派发更新过程

  • 修改响应式数据时触发 setter,调用 dep.notify() 通知所有订阅的 Watcher 更新。
  • Watcher 更新可能触发重新渲染或重新计算,形成闭环。

关键代码示例

// 简化版 Observer 实现
class Observer {
  constructor(value) {
    this.value = value
    this.walk(value)
  }

  walk(obj) {
    Object.keys(obj).forEach(key => {
      defineReactive(obj, key, obj[key])
    })
  }
}

function defineReactive(obj, key, val) {
  const dep = new Dep()
  Object.defineProperty(obj, key, {
    get() {
      if (Dep.target) {
        dep.depend()
      }
      return val
    },
    set(newVal) {
      if (newVal === val) return
      val = newVal
      dep.notify()
    }
  })
}

// Dep 实现
class Dep {
  constructor() {
    this.subs = []
  }

  depend() {
    if (Dep.target) {
      Dep.target.addDep(this)
    }
  }

  notify() {
    this.subs.forEach(watcher => watcher.update())
  }
}

// Watcher 实现
class Watcher {
  constructor(getter) {
    this.getter = getter
    this.get()
  }

  get() {
    pushTarget(this)
    this.value = this.getter()
    popTarget()
    return this.value
  }

  update() {
    this.get()
  }
}

现代 Vue 3 的改进

Vue 3 使用 Proxy 替代 Object.defineProperty,解决了以下问题:

  • 可检测数组索引修改和 length 变化
  • 支持动态添加新属性
  • 性能更好

依赖收集原理类似,但实现更简洁:

const reactive = (target) => {
  return new Proxy(target, {
    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)
    }
  })
}

性能优化策略

  • 组件级依赖收集:每个组件对应一个渲染 Watcher,减少不必要的更新
  • 异步更新队列:多次数据变化合并为一次更新
  • 计算属性缓存:依赖不变时直接返回缓存值
  • v-once 指令:标记静态内容避免重复渲染

vue实现依赖收集

标签: vue
分享给朋友:

相关文章

vue 移动端实现签名

vue 移动端实现签名

Vue 移动端签名实现方法 在移动端实现签名功能,可以通过HTML5的Canvas结合触摸事件完成。以下是具体实现步骤: 使用Canvas绘制签名 安装vue-signature-pad插件或直…

vue实现一个标签选择

vue实现一个标签选择

Vue 标签选择组件实现 基础实现 使用 Vue 的 v-for 和 v-model 指令可以快速实现标签选择功能: <template> <div class="tag-se…

vue实现发表

vue实现发表

Vue 实现发表功能 在 Vue 中实现发表功能通常涉及表单处理、数据绑定和网络请求。以下是实现步骤和代码示例: 表单设计与数据绑定 创建一个表单用于输入发表内容,使用 v-model 进行数据双向…

vue全选实现

vue全选实现

Vue 全选实现方法 在 Vue 中实现全选功能通常涉及数据绑定和事件处理。以下是几种常见的实现方式: 基础实现方式 <template> <div> <i…

vue实现语音

vue实现语音

Vue 实现语音功能的方法 使用 Web Speech API Vue 可以结合 Web Speech API 实现语音识别和合成功能。Web Speech API 包含 SpeechRecognit…

vue实现fadein

vue实现fadein

Vue 实现 FadeIn 效果 在 Vue 中实现淡入(FadeIn)效果可以通过 CSS 过渡、动画或第三方库实现。以下是几种常见方法: 使用 CSS 过渡 通过 Vue 的过渡系统结合 CS…