欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Vue3 的批量渲染機制的兩種方法

 更新時間:2025年10月30日 11:26:44   作者:CptW  
本文主要介紹了Vue3 的批量渲染機制的兩種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

兩種機制分別指:

  1. 在 1次 回調(diào)里觸發(fā) 多次 computed/effect,其只會執(zhí)行 1次
  2. 在 1次 回調(diào)里 多次 更新與視圖相關(guān)的 ref,視圖更新 也只執(zhí)行 1次

舉兩個例子:

// effectA
effect(() => {
  console.log('A:', a.value)
  if (a.value > 5) {
    // 2、再觸發(fā)第2次 effectB
    b.value = a.value * 2
  }
})

// effectB
effect(() => {
  console.log('B:', b.value)
})

// 1、更新dep, 觸發(fā)1次 effectA 和 1次 effectB
a.value = 6
// 實際 effectB 只會執(zhí)行 1 次,而不是 2 次
btn.onclick = () => {
  count.value++
  count.value++
  count.value++
  count.value++
}

return () => {
  console.log('render call')
  return h('div', `count: ${count.value}`)
}
// 點擊按鈕,實際 'render call' 只會被打印1次

如何實現(xiàn)的?簡寫源碼 來說明: PS: 不熟悉響應(yīng)式基礎(chǔ)的,請移步往期文章

effect的批處理

修改響應(yīng)式變量的值后,會觸發(fā) setter 里的函數(shù) trigger,之后會沿著鏈表通知所有 effect

export function traggerRef(dep: RefImpl) {
  ......
    propagate(dep.subs)
  ......
}

/** 傳播更新 */
export function propagate(subs: Link) {
  // 鏈表節(jié)點
  let link = subs
  // 收集 effect
  const queuedEffect = []
  while (link) {
    const sub = link.sub
    // 標(biāo)記 dirty,防止重復(fù)觸發(fā) effect
    if (!sub.tracking && !sub.dirty) {
      sub.dirty = true
      // ......
      queuedEffect.push(sub)
      // ......
    }
    // 遍歷鏈表
    link = link.nextSub
  }

  // 通知 effect 執(zhí)行
  queuedEffect.forEach(effect => effect.notify())
}

可以看到 sub 里有一個 dirty 屬性,如果同一次回調(diào)函數(shù)中,多次觸發(fā) sub,它只會被放入待執(zhí)行列表 1 次,也就是不會多次執(zhí)行。

注意,dirty 標(biāo)志位會等 Effect 真正執(zhí)行完成后才重置。

異步渲染render

mount組件的流程是:使用VNode創(chuàng)建組件實例instance -> 掛載到DOM -> 更新,組件實際上就是創(chuàng)建了一個 Effect 來訂閱更新:

const mountComponent = (vnode, container, anchor) => {
    /**
     * 1、創(chuàng)建組件實例
     * 2、初始化狀態(tài)
     * 3、掛載到DOM
     */
    // 1 實例化
    const instance = createComponentInstance(vnode)
    // 2 初始化
    setupComponent(instance)

    const componentUpdateFn = () => {
      // 首次掛載
      if (!instance.isMounted) {
        // 得到 Virtual DOM
        const subTree = instance.render()
        // 3 掛載
        patch(null, subTree, container, anchor)
        // 保存當(dāng)前 V-DOM
        instance.subTree = subTree
        // 修改標(biāo)志位
        instance.isMounted = true
      } else {
        // 更新
        const preSubTree = instance.subTree
        // 獲取新的 V-DOM
        const subTree = instance.render()
        // 對比新舊 VNode,更新
        patch(preSubTree, subTree, container, anchor)
        instance.subTree = subTree
      }
    }

    const effect = new ReactiveEffect(componentUpdateFn)
    const update = effect.run.bind(effect)

    instance.update = update

    effect.scheduler = () => {
      queueJob(update)
    }

    effect.run()
  }

但假如有如下例子,假如點擊 1次 按鈕,將打印 4次 effect execute 和 1次 render call

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
  </head>
  <body>
    <div id="app"></div>
    <button id="btn">+++</button>
    <script type="module">
      import { createApp, h, ref, effect, computed } from 'vue'

      const rootComp = {
        setup() {
          const count = ref(0)

          btn.onclick = () => {
            count.value++
            count.value++
            count.value++
            count.value++
          }

          effect(() => {
            console.log('effect execute', count.value)
          })

          return () => {
            console.log('render call')
            return h('div', `count1: ${count.value}`)
          }
        },
      }

      createApp(rootComp).mount('#app')
    </script>
  </body>
</html>

按理說 render call 也應(yīng)該打印 4次,Why? 因為代碼里利用 Effect.scheduler 做了 異步更新,即重寫了scheduler:

const componentUpdateFn = () => {
  //......
  const update = effect.run.bind(effect)

  instance.update = update

  effect.scheduler = () => {
    queueJob(update)
  }
  //......
}

function queueJob(job) {
  Promise.resolve().then(() => {
    job()
  })
}

此時,每次 ref 更新后,不立即重置 dirty,而是等所有同步任務(wù)執(zhí)行完后,再執(zhí)行渲染,BINGO

到此這篇關(guān)于Vue3 的批量渲染機制的兩種方法的文章就介紹到這了,更多相關(guān)Vue3 批量渲染內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Element如何實現(xiàn)loading的方法示例

    Element如何實現(xiàn)loading的方法示例

    本文主要介紹了Element如何實現(xiàn)loading的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • 詳解Nuxt.js部署及踩過的坑

    詳解Nuxt.js部署及踩過的坑

    這篇文章主要介紹了詳解Nuxt.js部署及踩過的坑,Nuxt.js 提供了兩種發(fā)布部署應(yīng)用的方式:服務(wù)端渲染應(yīng)用部署 和 靜態(tài)應(yīng)用部署。本文主要說說服務(wù)端渲染應(yīng)用部署,感興趣的小伙伴們可以參考一下
    2018-08-08
  • vue動態(tài)繪制四分之三圓環(huán)圖效果

    vue動態(tài)繪制四分之三圓環(huán)圖效果

    這篇文章主要介紹了vue動態(tài)繪制四分之三圓環(huán)圖效果,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-09-09
  • 詳解vue3.0 的 Composition API 的一種使用方法

    詳解vue3.0 的 Composition API 的一種使用方法

    這篇文章主要介紹了vue3.0 的 Composition API 的一種使用方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-10-10
  • 解決vue動態(tài)下拉菜單 有數(shù)據(jù)未反應(yīng)的問題

    解決vue動態(tài)下拉菜單 有數(shù)據(jù)未反應(yīng)的問題

    這篇文章主要介紹了解決vue動態(tài)下拉菜單 有數(shù)據(jù)未反應(yīng)的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • vue.js 使用v-if v-else發(fā)現(xiàn)沒有執(zhí)行解決辦法

    vue.js 使用v-if v-else發(fā)現(xiàn)沒有執(zhí)行解決辦法

    這篇文章主要介紹了vue.js 使用v-if v-else發(fā)現(xiàn)沒有執(zhí)行解決辦法的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • vue-router 組件復(fù)用問題詳解

    vue-router 組件復(fù)用問題詳解

    本篇文章主要介紹了vue-router 組件復(fù)用問題詳解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Vue包大小優(yōu)化的實現(xiàn)(從1.72M到94K)

    Vue包大小優(yōu)化的實現(xiàn)(從1.72M到94K)

    這篇文章主要介紹了Vue包大小優(yōu)化的實現(xiàn)(從1.72M到94K),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • vue3?hook自動導(dǎo)入原理解析

    vue3?hook自動導(dǎo)入原理解析

    這篇文章主要介紹了vue3?hook自動導(dǎo)入的原理,介紹了API的自動導(dǎo)入及組件的自動導(dǎo)入,本文結(jié)合實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • vue實現(xiàn)裁切圖片同時實現(xiàn)放大、縮小、旋轉(zhuǎn)功能

    vue實現(xiàn)裁切圖片同時實現(xiàn)放大、縮小、旋轉(zhuǎn)功能

    這篇文章主要介紹了vue實現(xiàn)裁切圖片同時實現(xiàn)放大、縮小、旋轉(zhuǎn)功能,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03

最新評論