<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      [vue3] patchFlags與位運(yùn)算

      Vue3在編譯template的過(guò)程中會(huì)分析模板中的動(dòng)態(tài)部分和靜態(tài)部分,并標(biāo)記相應(yīng)的flag,用于在運(yùn)行時(shí)優(yōu)化虛擬DOM的更新。

      • Parse:將模板字符串解析成AST
      • Transform:對(duì)AST進(jìn)行轉(zhuǎn)換和優(yōu)化,包括識(shí)別動(dòng)態(tài)節(jié)點(diǎn)和靜態(tài)節(jié)點(diǎn);
      • CodeGeneration:將轉(zhuǎn)換后的AST生成渲染函數(shù),這個(gè)階段會(huì)生成patchFlags

      diff過(guò)程中,遇到包含dynamicChildren的塊時(shí),diff算法會(huì)進(jìn)入優(yōu)化模式,跳過(guò)對(duì)靜態(tài)節(jié)點(diǎn)的處理從而優(yōu)化了diff的執(zhí)行效率。

      flag的種類

      源碼位置core/packages/shared/src/patchFlags.ts at main · vuejs/core (github.com)

      export enum PatchFlags {
        TEXT = 1,
        CLASS = 1 << 1,
        STYLE = 1 << 2,
        PROPS = 1 << 3,
        FULL_PROPS = 1 << 4,
        NEED_HYDRATION = 1 << 5,
        STABLE_FRAGMENT = 1 << 6,
        KEYED_FRAGMENT = 1 << 7,
        UNKEYED_FRAGMENT = 1 << 8,
        NEED_PATCH = 1 << 9,
        DYNAMIC_SLOTS = 1 << 10,
        DEV_ROOT_FRAGMENT = 1 << 11,
          
        HOISTED = -1,
        BAIL = -2,
      }
      

      可以看到flag使用二進(jìn)制格式記錄的,并且每個(gè)標(biāo)志僅有一位為1,這樣可以通過(guò)位運(yùn)算獲知一個(gè)復(fù)合狀態(tài)里包含哪些狀態(tài)。

      flag含義

      • TEXT:表示元素具有動(dòng)態(tài)的 textContent

        <div>{{ dynamicText }}</div>
        
      • CLASS:表示元素具有動(dòng)態(tài)的類綁定。

        <template>
          <div :class="dynamicClass">Content</div>
        </template>
        
        <script>
        export default {
          data() {
            return {
              dynamicClass: 'active'
            }
          }
        }
        </script>
        
      • STYLE:表示元素具有動(dòng)態(tài)樣式。

        <template>
          <div :style="dynamicStyle">Content</div>
        </template>
        
        <script>
        export default {
          data() {
            return {
              dynamicStyle: {
                color: 'red'
              }
            }
          }
        }
        </script>
        
      • PROPS:表示元素具有非 class/style 的動(dòng)態(tài)屬性。也可以用于具有任何動(dòng)態(tài)屬性的組件。

        <template>
          <input :value="dynamicValue" />
        </template>
        
        <script>
        export default {
          data() {
            return {
              dynamicValue: 'Hello'
            }
          }
        }
        </script>
        
      • FULL_PROPS:表示具有動(dòng)態(tài)鍵屬性的元素。當(dāng)鍵變化時(shí),總是需要完全差異檢查。

        <template>
          <div v-bind:[dynamicProp]="dynamicValue">Content</div>
        </template>
        
        <script>
        export default {
          data() {
            return {
              dynamicProp: 'id',
              dynamicValue: 'uniqueId'
            }
          }
        }
        </script>
        
      • NEED_HYDRATION:表示該元素在客戶端渲染時(shí),需要將屬性從靜態(tài) HTML轉(zhuǎn)換為動(dòng)態(tài)綁定。hydration是指從服務(wù)器端渲染(SSR)的靜態(tài)內(nèi)容中恢復(fù)出動(dòng)態(tài)行為和狀態(tài)的過(guò)程。該元素不需要常規(guī)的虛擬 DOM 屬性更新,只需要在初始化時(shí)處理特定的屬性以恢復(fù)其動(dòng)態(tài)行為。

        案例(事件監(jiān)聽(tīng)器):如 @click="handler",在服務(wù)器端渲染時(shí),事件綁定不會(huì)被實(shí)際添加,客戶端加載后需要將事件監(jiān)聽(tīng)器正確綁定到元素上。

        <template>
          <button @click="handleClick">Click me</button>
        </template>
        
        <script>
        export default {
          methods: {
            handleClick() {
              console.log('Button clicked!')
            }
          }
        }
        </script>
        
      • STABLE_FRAGMENT:表示子元素順序不變的片段。

      • KEYED_FRAGMENT:表示子元素的都帶有或部分帶有key標(biāo)注。

      • UNKEYED_FRAGMENT:表示子元素沒(méi)有key標(biāo)注的片段。

      • NEED_PATCH:表示不涉及classstyleprops但仍需觸發(fā)更新的情況,通常對(duì)應(yīng)ref、指令等使用場(chǎng)景。

      • DYNAMIC_SLOTS:主要用于標(biāo)識(shí)那些插槽內(nèi)容或插槽名稱是動(dòng)態(tài)變化的組件。帶有此標(biāo)志的組件在更新時(shí)會(huì)被強(qiáng)制更新,以確保插槽內(nèi)容或名稱的變化能夠正確反映到 DOM 中。

        <template>
          <parent-component>
            <template :slot="dynamicSlotName">
              <child-component :data="someData" />
            </template>
          </parent-component>
        </template>
        
        <script>
        export default {
          data() {
            return {
              dynamicSlotName: 'defaultSlot',
              someData: { message: 'Hello, World!' }
            }
          }
        }
        </script>
        
      • DEV_ROOT_FRAGMENT:表示用戶在template的頂層寫了注釋而創(chuàng)建的flag。僅用于開(kāi)發(fā)環(huán)境,因?yàn)樯a(chǎn)中會(huì)去除注釋。

        <template>
          <!-- Root level comment -->
          <div>Content</div>
        </template>
        
      • HOISTED:表示提升的靜態(tài)虛擬節(jié)點(diǎn)。patch過(guò)程可以跳過(guò)整個(gè)子樹,因?yàn)殪o態(tài)內(nèi)容永遠(yuǎn)不需要更新。

        <p>Static content</p>
        
      • BAIL:表示diff算法應(yīng)退出優(yōu)化模式,通常是對(duì)應(yīng)用戶使用h函數(shù)自定義渲染函數(shù)的情況。

      示例代碼

      vue3有提供一個(gè)playground可以查看編譯后的結(jié)果:Vue SFC Playground (vuejs.org)

      簡(jiǎn)單的代碼案例

      <script setup>
      import { ref } from 'vue'
      
      const msg = ref('Hello World!')
      </script>
      
      <template>
        <p>static content</p>
        <h1>{{ msg }}</h1>
        <input v-model="msg" />
      </template>
      

      編譯后的JS

      import { ref } from 'vue'
      
      
      const __sfc__ = {
        __name: 'App',
        setup(__props, { expose: __expose }) {
        __expose();
      
      const msg = ref('Hello World!')
      
      const __returned__ = { msg, ref }
      Object.defineProperty(__returned__, '__isScriptSetup', { enumerable: false, value: true })
      return __returned__
      }
      
      };
      import { createElementVNode as _createElementVNode, toDisplayString as _toDisplayString, vModelText as _vModelText, withDirectives as _withDirectives, Fragment as _Fragment, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"
      
      const _hoisted_1 = /*#__PURE__*/_createElementVNode("p", null, "static content", -1 /* HOISTED */)
      function render(_ctx, _cache, $props, $setup, $data, $options) {
        return (_openBlock(), _createElementBlock(_Fragment, null, [
          _hoisted_1,
          _createElementVNode("h1", null, _toDisplayString($setup.msg), 1 /* TEXT */),
          _withDirectives(_createElementVNode("input", {
            "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($setup.msg) = $event))
          }, null, 512 /* NEED_PATCH */), [
            [_vModelText, $setup.msg]
          ])
        ], 64 /* STABLE_FRAGMENT */))
      }
      __sfc__.render = render
      __sfc__.__file = "src/App.vue"
      export default __sfc__
      
      • 可以看到<p>static content</p>被應(yīng)用了靜態(tài)提升(Vue3優(yōu)化策略之一):

      (靜態(tài)的flag-1

      const _hoisted_1 = /*#__PURE__*/_createElementVNode("p", null, "static content", -1 /* HOISTED */)
      
      • <h1>{{ msg }}</h1>由于有動(dòng)態(tài)文本,被標(biāo)記為TEXT
      • <input v-model="msg" />使用了v-model指令,被標(biāo)記了NEED_PATCH
      • Vue2template內(nèi)部只能存在一個(gè)頂級(jí)節(jié)點(diǎn),如果有多個(gè)要使用一個(gè)標(biāo)簽?zāi)依ㄆ渲校?code>Vue3支持template內(nèi)部多個(gè)頂級(jí)節(jié)點(diǎn),其實(shí)是框架幫我們套了一個(gè)fragment;在上述代碼中由于這個(gè)fragment內(nèi)部元素的順序是固定的,因此被標(biāo)記為STABLE_FRAGMENT

      靜態(tài)提升

      靜態(tài)提升是Vue3的一種性能優(yōu)化手段。如果有VNode被標(biāo)記為靜態(tài)節(jié)點(diǎn),說(shuō)明它的內(nèi)容是固定不變的。那么它的構(gòu)建函數(shù)會(huì)被提升到渲染函數(shù)的外部,即只會(huì)被運(yùn)行一次。

      位運(yùn)算的應(yīng)用

      Vue3中,這些flags都是只有一位為1,在這個(gè)前提下,可以通過(guò)位運(yùn)算實(shí)現(xiàn)下面兩種操作:

      組合標(biāo)志

      通過(guò)或運(yùn)算組合標(biāo)志:

      const combinedFlag = PatchFlags.TEXT | PatchFlags.STYLE; // 0001 | 0100 = 0101
      

      檢查標(biāo)志

      通過(guò)與運(yùn)算檢查混合標(biāo)志是否存在某個(gè)base flag

      const hasText = combinedFlag & PatchFlags.TEXT; // 0101 & 0001 = 0001 (truthy)
      const hasClass = combinedFlag & PatchFlags.CLASS; // 0101 & 0010 = 0000 (falsy)
      

      可以在源碼中看到patchFlag和與運(yùn)算的相關(guān)代碼:core/packages/runtime-core/src/renderer.ts at main · vuejs/core (github.com)

      image-20240803181837861

      posted @ 2024-08-03 18:24  feixianxing  閱讀(167)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 色噜噜在线视频免费观看| 亚洲一区二区三区av链接| 久久亚洲精品情侣| 日韩精品一区二区亚洲专区| 国产成人午夜福利在线观看| 亚洲欧美日韩愉拍自拍| 男人天堂亚洲天堂女人天堂| 亚洲中文字幕一区二区| 国产性天天综合网| 色综合天天综合网天天看片| 九九热在线观看视频免费| 欧美日韩免费专区在线观看| 久久人人妻人人爽人人爽| 亚洲熟女乱一区二区三区| 久久精品国产99久久无毒不卡| 久久一区二区中文字幕| 成人网站免费在线观看| 黄色A级国产免费大片视频| 一二三四区无产乱码1000集| 在线精品另类自拍视频| 大尺度国产一区二区视频| 丰满少妇高潮无套内谢| 清水河县| 少妇真人直播免费视频| 人妻人人做人做人人爱| 国产精品久久蜜臀av| 国产成人无码A区在线观看视频 | 国内偷自第一区二区三区| 美女黄网站18禁免费看| 亚洲第一香蕉视频啪啪爽| 日韩一本不卡一区二区三区| 一本色道久久综合亚洲精品不卡| 97se亚洲国产综合在线| 亚洲综合精品一区二区三区| 亚洲欧洲日产国无高清码图片| 成人天堂资源www在线| 九九热精品在线观看| 草草浮力影院| 性色a∨精品高清在线观看| 国产av亚洲精品ai换脸电影| 91麻豆亚洲国产成人久久|