最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue?3?effect作用與原理解析

 更新時(shí)間:2025年02月07日 08:55:11   作者:啊哈哈哈哈哈h  
Vue3的Effect是其響應(yīng)式系統(tǒng)的核心,負(fù)責(zé)依賴追蹤和自動(dòng)響應(yīng),它通過(guò)ReactiveEffect類(lèi)封裝副作用邏輯,實(shí)現(xiàn)依賴收集和觸發(fā)更新,本文介紹vue?3?effect作用與原理解析,感興趣的朋友一起看看吧

Vue 3 的 Effect(副作用) 是整個(gè)響應(yīng)式系統(tǒng)的核心機(jī)制,負(fù)責(zé)管理依賴追蹤和響應(yīng)式觸發(fā)。理解其作用和原理對(duì)掌握 Vue 的底層機(jī)制至關(guān)重要。

一、核心作用

1. 依賴追蹤(Dependency Tracking)

  • 自動(dòng)跟蹤響應(yīng)式數(shù)據(jù)在副作用函數(shù)中的使用。

示例代碼

import { reactive, effect } from 'vue'
const obj = reactive({ count: 0 })
effect(() => {
  console.log(`count is: ${obj.count}`)
})
  • 當(dāng)首次執(zhí)行 effect 時(shí),函數(shù) () => console.log(...) 會(huì)被運(yùn)行。
  • 觸發(fā) obj.count 的 get 操作,觸發(fā)依賴收集(將當(dāng)前 effect 關(guān)聯(lián)到 obj.count)。

2. 自動(dòng)響應(yīng)(Automatic Re-run)

當(dāng)響應(yīng)式數(shù)據(jù)的依賴變化時(shí),自動(dòng)重新執(zhí)行副作用函數(shù):

obj.count++  // 觸發(fā)依賴更新,控制臺(tái)打印 "count is: 1"

3. 支撐高級(jí) API

  • computedwatch、組件渲染函數(shù)等底層都依賴于 effect 實(shí)現(xiàn)。

二、實(shí)現(xiàn)原理

1. 核心類(lèi):ReactiveEffect

Vue 3 用 ReactiveEffect 類(lèi)封裝副作用邏輯,簡(jiǎn)化后的源碼結(jié)構(gòu)如下:

class ReactiveEffect<T = any> {
  // 當(dāng)前 effect 的所有依賴項(xiàng)(其他響應(yīng)式對(duì)象)
  deps: Dep[] = []
  // 構(gòu)造函數(shù)參數(shù)
  constructor(
    public fn: () => T,            // 副作用函數(shù)
    public scheduler?: () => void  // 調(diào)度函數(shù)(控制重新執(zhí)行方式)
  ) {}
  // 運(yùn)行副作用(觸發(fā)依賴收集)
  run() {
    activeEffect = this // 標(biāo)記當(dāng)前正在運(yùn)行的 effect
    try {
      return this.fn()
    } finally {
      activeEffect = undefined
    }
  }
  // 停止偵聽(tīng)
  stop() { /* 從所有依賴中移除自身 */ }
}

2. 依賴收集流程(Track)

數(shù)據(jù)結(jié)構(gòu)

type Dep = Set<ReactiveEffect>    // 依賴集合
type TargetMap = WeakMap<Object, Map<string, Dep>> // 全局依賴存儲(chǔ)
  • 觸發(fā)時(shí)機(jī):響應(yīng)式數(shù)據(jù)的 get 操作觸發(fā)時(shí)。
  • 流程

    根據(jù)響應(yīng)式對(duì)象 (target) 和鍵 (key) 找到存入 targetMap 的依賴集合 (dep)。

    將當(dāng)前活躍的 activeEffect 添加到 dep 中。

    同時(shí)將 dep 加入 activeEffect.deps(反向記錄,用于 cleanup)。

3. 觸發(fā)更新(Trigger)

  • 觸發(fā)時(shí)機(jī):響應(yīng)式數(shù)據(jù)的 set 操作時(shí)。
  • 流程

    根據(jù) target 和 key 從 targetMap 獲取對(duì)應(yīng)的 dep 集合。

    遍歷 dep 中所有 effect

    • 如果有 scheduler(如 computed),執(zhí)行調(diào)度器(優(yōu)化性能)。
    • 否則直接執(zhí)行 effect.run()。

4. 調(diào)度器(Scheduler)

允許控制 effect 如何重新執(zhí)行:

effect(() => {
  console.log(obj.count)
}, {
  scheduler(effect) { 
    // 如將 effect 推入微任務(wù)隊(duì)列中異步執(zhí)行
    queueMicrotask(effect.run) 
  }
})
  • 應(yīng)用場(chǎng)景:
    • watch 的異步批處理更新。
    • computed 的值懶更新。

三、關(guān)鍵優(yōu)化設(shè)計(jì)

1. 嵌套 Effect 棧

用棧結(jié)構(gòu) effectStack 跟蹤嵌套的 effect:

function run() {
  if (!effectStack.includes(this)) {
    try {
      effectStack.push((activeEffect = this))
      return this.fn()
    } finally {
      effectStack.pop()
      activeEffect = effectStack[effectStack.length - 1]
    }
  }
}
  • 解決問(wèn)題:組件嵌套時(shí)的依賴關(guān)系混亂。

2. Cleanup 機(jī)制

每次 effect 執(zhí)行前清理舊依賴:

function run() {
  cleanup(this) // 清理之前收集的舊依賴
  // ...然后重新收集新依賴
}
  • 解決問(wèn)題:動(dòng)態(tài)分支邏輯導(dǎo)致的無(wú)效依賴(如 v-if 切換導(dǎo)致的條件依賴)。

3. Lazy 執(zhí)行

可配置不立即執(zhí)行 effect:

const runner = effect(fn, { lazy: true })
runner() // 手動(dòng)執(zhí)行
  • 應(yīng)用場(chǎng)景computed 屬性初始化時(shí)延遲計(jì)算。

四、與 Vue 各組件的關(guān)聯(lián)

1. 組件渲染

組件 render 函數(shù)被包裹在 effect 中:

function setupRenderEffect(instance) {
  effect(() => {
    const subTree = instance.render.call(instance.proxy)
    patch(instance.subTree, subTree)
    instance.subTree = subTree
  }, { scheduler: queueJob }) // 異步更新隊(duì)列
}

2. Computed 實(shí)現(xiàn)

computed 通過(guò) effect + 調(diào)度器實(shí)現(xiàn)懶更新:

const computedRef = new ComputedRefImpl(
  getter,
  () => { // 調(diào)度器
    if (!this._dirty) {
      this._dirty = true
      trigger(this, 'set', 'value')
    }
  }
)

3. Watch API

watch 基于 effect 的調(diào)度器實(shí)現(xiàn)異步回調(diào):

function watch(source, cb, { flush } = {}) {
  let scheduler
  if (flush === 'sync') {
    scheduler = cb
  } else { // 'post' 或其他默認(rèn)情況
    scheduler = () => queuePostFlushCb(cb)
  }
  effect(() => traverse(source), { scheduler })
}

五、與 Vue 2 的對(duì)比

特性Vue 2 (Watcher)Vue 3 (Effect)
依賴追蹤通過(guò)遍歷數(shù)據(jù)觸發(fā) getter通過(guò) Proxy/Reflect 自動(dòng)追蹤
更新粒度依賴組件級(jí)檢查基于精確依賴的靶向更新
性能優(yōu)化需手寫(xiě) pureComputed 等內(nèi)置自動(dòng)的依賴清理和調(diào)度機(jī)制
內(nèi)存管理易產(chǎn)生內(nèi)存泄漏(舊 Dep 引用問(wèn)題)通過(guò) WeakMap 自動(dòng)釋放無(wú)用依賴

六、源碼流程圖解

+---------------------+
|   Reactive Object   |
+----------+----------+
           │ 訪問(wèn)屬性時(shí)
           ▼
+---------------------+
|   觸發(fā) get 代理     +----→ track(target, key)
+---------------------+         │
           ▲                    ▼ 存儲(chǔ)依賴關(guān)系
           │          +---------------------+
           +----------+    targetMap        |
                      | (WeakMap結(jié)構(gòu))        |
                      +---------+-----------+
                                │
                                ▼
                      +---------------------+
                      |   depsMap (Map)     |
                      | (key → Dep Set)      |
                      +---------+-----------+
                                │
                                ▼
                      +---------------------+
                      |   dep (Set)         |
                      | (存儲(chǔ)所有關(guān)聯(lián)的 effect)|
                      +---------------------+

總結(jié)

Vue 3 的 effect 通過(guò)以下機(jī)制成為響應(yīng)式系統(tǒng)的核心:

  • Proxy 依賴收集:精確追蹤響應(yīng)式數(shù)據(jù)的使用。
  • 調(diào)度器控制:提供靈活的回調(diào)執(zhí)行方式。
  • 內(nèi)存安全:通過(guò) WeakMap 自動(dòng)管理依賴。
  • 框架級(jí)優(yōu)化:支持組件渲染、計(jì)算屬性、watch 等核心功能。

到此這篇關(guān)于vue 3 effect作用與原理的文章就介紹到這了,更多相關(guān)vue 3 effect作用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

甘泉县| 新源县| 临泉县| 四子王旗| 绵阳市| 泾源县| 永修县| 濉溪县| 沁水县| 定边县| 阳朔县| 聂荣县| 嘉峪关市| 长丰县| 银川市| 桐梓县| 沂南县| 济源市| 大悟县| 大化| 金山区| 合阳县| 建德市| 府谷县| 顺平县| 夏津县| 曲阳县| 龙泉市| 安乡县| 永仁县| 彭泽县| 沅陵县| 夏河县| 阿克苏市| 宝应县| 广德县| 马龙县| 两当县| 双辽市| 穆棱市| 南陵县|