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

Vue3 的批量渲染機(jī)制的兩種方法

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

兩種機(jī)制分別指:

  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
// 實(shí)際 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}`)
}
// 點(diǎn)擊按鈕,實(shí)際 'render call' 只會被打印1次

如何實(shí)現(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é)點(diǎn)
  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)建組件實(shí)例instance -> 掛載到DOM -> 更新,組件實(shí)際上就是創(chuàng)建了一個 Effect 來訂閱更新:

const mountComponent = (vnode, container, anchor) => {
    /**
     * 1、創(chuàng)建組件實(shí)例
     * 2、初始化狀態(tài)
     * 3、掛載到DOM
     */
    // 1 實(shí)例化
    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()
  }

但假如有如下例子,假如點(diǎn)擊 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 的批量渲染機(jī)制的兩種方法的文章就介紹到這了,更多相關(guān)Vue3 批量渲染內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue自動生成組件示例總結(jié)

    Vue自動生成組件示例總結(jié)

    在Vue中,我們可以使用unplugin-generate-component-name插件自動基于目錄名稱生成組件名稱,這個插件使得在大型代碼庫中找到和管理組件更加容易和直觀,這篇文章主要介紹了Vue自動生成組件示例總結(jié),需要的朋友可以參考下
    2023-12-12
  • vue如何實(shí)現(xiàn)el-select下拉選項的懶加載

    vue如何實(shí)現(xiàn)el-select下拉選項的懶加載

    這篇文章主要介紹了vue如何實(shí)現(xiàn)el-select下拉選項的懶加載,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • vue3如何利用自定義指令實(shí)現(xiàn)下拉框分頁懶加載

    vue3如何利用自定義指令實(shí)現(xiàn)下拉框分頁懶加載

    下拉框一開始請求第一頁的內(nèi)容,滾動到最后的時候,請求第二頁的內(nèi)容,如此反復(fù),直到所有數(shù)據(jù)加載完成,這篇文章主要介紹了vue3如何利用自定義指令實(shí)現(xiàn)下拉框分頁懶加載,需要的朋友可以參考下
    2024-07-07
  • element表格數(shù)據(jù)部分模糊的實(shí)現(xiàn)代碼

    element表格數(shù)據(jù)部分模糊的實(shí)現(xiàn)代碼

    這篇文章給大家介紹了element表格數(shù)據(jù)模糊的實(shí)現(xiàn)代碼,文中有詳細(xì)的效果展示和實(shí)現(xiàn)代碼供大家參考,具有一定的參考價值,需要的朋友可以參考下
    2024-01-01
  • 關(guān)于vue2使用element?UI中Descriptions組件的遍歷問題詳解

    關(guān)于vue2使用element?UI中Descriptions組件的遍歷問題詳解

    最近element-ui遇到了很多坑,下面這篇文章主要給大家介紹了關(guān)于vue2使用element?UI中Descriptions組件的遍歷問題,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • vue通過過濾器實(shí)現(xiàn)數(shù)據(jù)格式化

    vue通過過濾器實(shí)現(xiàn)數(shù)據(jù)格式化

    這篇文章主要介紹了vue通過過濾器實(shí)現(xiàn)數(shù)據(jù)格式化的方法,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • Vue3.0?axios跨域請求代理服務(wù)器配置方式

    Vue3.0?axios跨域請求代理服務(wù)器配置方式

    這篇文章主要介紹了Vue3.0?axios跨域請求代理服務(wù)器配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue3.2?中新出的Expose用法一覽

    Vue3.2?中新出的Expose用法一覽

    這篇文章主要介紹了Vue3.2?中新出的?Expose?是做啥用的,新的expose方法是非常直觀的,而且很容易在我們的組件中實(shí)現(xiàn),本文給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • vue 地圖可視化 maptalks 篇實(shí)例代碼詳解

    vue 地圖可視化 maptalks 篇實(shí)例代碼詳解

    這篇文章主要介紹了vue 地圖可視化 maptalks 篇,本文分步驟通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值 ,需要的朋友可以參考下
    2019-05-05
  • IDEA中Debug調(diào)試VUE前端項目調(diào)試JS只需兩步

    IDEA中Debug調(diào)試VUE前端項目調(diào)試JS只需兩步

    這篇文章主要為大家介紹了在IDEA中Debug調(diào)試VUE前端項目,只需要兩步就可以調(diào)試JS的實(shí)現(xiàn)方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-02-02

最新評論

肥西县| 宝丰县| 通城县| 高平市| 梧州市| 普陀区| 会泽县| 普宁市| 湾仔区| 大同市| 依兰县| 铁岭县| 乌兰察布市| 句容市| 东平县| 鹤岗市| 昭通市| 社旗县| 潼南县| 开江县| 泌阳县| 吉水县| 东阳市| 遂宁市| 于都县| 临湘市| 甘谷县| 博兴县| 河西区| 惠州市| 金坛市| 虎林市| 甘泉县| 杭州市| 株洲县| 三亚市| 平阳县| 九龙坡区| 高邮市| 菏泽市| 凌云县|