当前位置:首页 > 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中实现打字机效果可以通过动态更新文本内容并添加延迟来实现。以下是几种常见的实现方法: 使用setInterval实现 <template> <di…

vue动态组建实现原理

vue动态组建实现原理

Vue 动态组件的实现原理 Vue 的动态组件主要通过 component 标签和 is 属性实现,核心原理涉及组件的动态切换和渲染机制。 动态组件的实现方式 使用 component 标签和 i…

vue实现字母添加排序

vue实现字母添加排序

实现字母添加排序的方法 在Vue中实现字母添加排序功能,可以通过以下步骤完成: 创建Vue实例并定义数据 new Vue({ el: '#app', data: { lette…

vue实现视窗

vue实现视窗

Vue 实现视窗功能 在 Vue 中实现视窗功能通常涉及监听浏览器窗口大小变化、响应式布局或创建自定义弹窗组件。以下是几种常见实现方式: 监听浏览器窗口大小变化 使用 Vue 的 mounted…

vue computed 实现

vue computed 实现

computed 的基本用法 在 Vue 中,computed 用于声明计算属性,这些属性基于响应式依赖进行缓存。只有当依赖发生变化时,计算属性才会重新计算。 new Vue({ data: {…

vue实现框架

vue实现框架

Vue 框架实现的核心方法 基础项目搭建 使用 Vue CLI 或 Vite 快速初始化项目。Vue CLI 适合传统项目,Vite 更适合现代轻量级应用。安装后通过命令行工具选择所需配置(如 Rou…