自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Vue3的defineAsyncComponent是如何實(shí)現(xiàn)異步組件的呢?

開(kāi)發(fā) 前端
createInnerComp?函數(shù)接收兩個(gè)參數(shù),第一個(gè)參數(shù)為要異步加載的vue組件對(duì)象。第二個(gè)參數(shù)為使用defineAsyncComponent創(chuàng)建的vue組件對(duì)應(yīng)的vue實(shí)例。

前言

在上一篇 給我5分鐘,保證教會(huì)你在vue3中動(dòng)態(tài)加載遠(yuǎn)程組件文章中,我們通過(guò)defineAsyncComponent實(shí)現(xiàn)了動(dòng)態(tài)加載遠(yuǎn)程組件。這篇文章我們將通過(guò)debug源碼的方式來(lái)帶你搞清楚defineAsyncComponent是如何實(shí)現(xiàn)異步組件的。注:本文使用的vue版本為3.4.19

看個(gè)demo

還是一樣的套路,我們來(lái)看個(gè)defineAsyncComponent異步組件的demo。

本地子組件local-child.vue代碼如下:

<template>
  <p>我是本地組件</p>
</template>

異步子組件async-child.vue代碼如下:

<template>
  <p>我是異步組件</p>
</template>

父組件index.vue代碼如下:

<template>
  <LocalChild />
  <button @click="showAsyncChild = true">load async child</button>
  <AsyncChild v-if="showAsyncChild" />
</template>

<script setup lang="ts">
import { defineAsyncComponent, ref } from "vue";
import LocalChild from "./local-child.vue";

const AsyncChild = defineAsyncComponent(() => import("./async-child.vue"));
const showAsyncChild = ref(false);
</script>

我們這里有兩個(gè)子組件,第一個(gè)local-child.vue,他和我們平時(shí)使用的組件一樣,沒(méi)什么說(shuō)的。

第二個(gè)子組件是async-child.vue,在父組件中我們沒(méi)有像普通組件local-child.vue那樣在最上面import導(dǎo)入,而是在defineAsyncComponent接收的回調(diào)函數(shù)中去動(dòng)態(tài)import導(dǎo)入async-child.vue文件,這樣定義的AsyncChild組件就是異步組件。

在template中可以看到,只有當(dāng)點(diǎn)擊load async child按鈕后才會(huì)加載異步組件AsyncChild。

我們先來(lái)看看執(zhí)行效果,如下gif圖:

圖片圖片

從上面的gif圖可以看到,當(dāng)我們點(diǎn)擊load async child按鈕后,在network面板中才會(huì)去加載異步組件async-child.vue。

defineAsyncComponent除了像上面這樣直接接收一個(gè)返回Promise的回調(diào)函數(shù)之外,還可以接收一個(gè)對(duì)象作為參數(shù)。demo代碼如下:

const AsyncComp = defineAsyncComponent({
  // 加載函數(shù)
  loader: () => import('./async-child.vue'),

  // 加載異步組件時(shí)使用的組件
  loadingComponent: LoadingComponent,
  // 展示加載組件前的延遲時(shí)間,默認(rèn)為 200ms
  delay: 200,

  // 加載失敗后展示的組件
  errorComponent: ErrorComponent,
  // 如果提供了一個(gè) timeout 時(shí)間限制,并超時(shí)了
  // 也會(huì)顯示這里配置的報(bào)錯(cuò)組件,默認(rèn)值是:Infinity
  timeout: 3000
})

其中對(duì)象參數(shù)有幾個(gè)字段:

  • loader字段其實(shí)對(duì)應(yīng)的就是前面那種寫(xiě)法中的回調(diào)函數(shù)。
  • loadingComponent為加載異步組件期間要顯示的loading組件。
  • delay為顯示loading組件的延遲時(shí)間,默認(rèn)200ms。這是因?yàn)樵诰W(wǎng)絡(luò)狀況較好時(shí),加載完成得很快,加載組件和最終組件之間的替換太快可能產(chǎn)生閃爍,反而影響用戶感受。
  • errorComponent為加載失敗后顯示的組件。
  • timeout為超時(shí)時(shí)間。

在接下來(lái)的源碼分析中,我們還是以前面那個(gè)接收一個(gè)返回Promise的回調(diào)函數(shù)為例子進(jìn)行debug調(diào)試源碼。

開(kāi)始打斷點(diǎn)

我們?cè)跒g覽器中接著來(lái)看父組件index.vue編譯后的代碼,很簡(jiǎn)單,在瀏覽器中可以像vscode一樣使用command(windows中是control)+p就可以喚起一個(gè)輸入框,然后在輸入框中輸入index.vue點(diǎn)擊回車(chē)就可以在source面板中打開(kāi)編譯后的index.vue文件了。如下圖:

圖片圖片

我們看到編譯后的index.vue文件代碼如下:

import { defineComponent as _defineComponent } from "/node_modules/.vite/deps/vue.js?v=868545d8";
import {
  defineAsyncComponent,
  ref,
} from "/node_modules/.vite/deps/vue.js?v=868545d8";
import LocalChild from "/src/components/defineAsyncComponentDemo/local-child.vue?t=1723193310324";
const _sfc_main = _defineComponent({
  __name: "index",
  setup(__props, { expose: __expose }) {
    __expose();
    const showAsyncChild = ref(false);
    const AsyncChild = defineAsyncComponent(() =>
      import("/src/components/defineAsyncComponentDemo/async-child.vue")
    );
    const __returned__ = { showAsyncChild, AsyncChild, LocalChild };
    return __returned__;
  },
});

function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  // ...省略
}

export default _export_sfc(_sfc_main, [["render", _sfc_render]]);

從上面的代碼可以看到編譯后的index.vue主要分為兩塊,第一塊為_(kāi)sfc_main對(duì)象中的setup方法,對(duì)應(yīng)的是我們的script模塊。第二塊為_(kāi)sfc_render,也就是我們常說(shuō)的render函數(shù),對(duì)應(yīng)的是template中的內(nèi)容。

我們想要搞清楚defineAsyncComponent方法的原理,那么當(dāng)然是給setup方法中的defineAsyncComponent方法打斷點(diǎn)。刷新頁(yè)面,此時(shí)代碼將會(huì)停留在斷點(diǎn)defineAsyncComponent方法處。

defineAsyncComponent方法

然后將斷點(diǎn)走進(jìn)defineAsyncComponent函數(shù)內(nèi)部,在我們這個(gè)場(chǎng)景中簡(jiǎn)化后的defineAsyncComponent函數(shù)代碼如下:

function defineAsyncComponent(source) {
  if (isFunction(source)) {
    source = { loader: source };
  }
  const { loader, loadingComponent, errorComponent, delay = 200 } = source;
  let resolvedComp;

  const load = () => {
    return loader()
      .catch(() => {
        // ...省略
      })
      .then((comp) => {
        if (
          comp &&
          (comp.__esModule || comp[Symbol.toStringTag] === "Module")
        ) {
          comp = comp.default;
        }
        resolvedComp = comp;
        return comp;
      });
  };

  return defineComponent({
    name: "AsyncComponentWrapper",
    setup() {
      const instance = currentInstance;
      const loaded = ref(false);
      const error = ref();
      const delayed = ref(!!delay);
      if (delay) {
        setTimeout(() => {
          delayed.value = false;
        }, delay);
      }
      load()
        .then(() => {
          loaded.value = true;
        })
        .catch((err) => {
          onError(err);
          error.value = err;
        });
      return () => {
        if (loaded.value && resolvedComp) {
          return createInnerComp(resolvedComp, instance);
        } else if (error.value && errorComponent) {
          return createVNode(errorComponent, {
            error: error.value,
          });
        } else if (loadingComponent && !delayed.value) {
          return createVNode(loadingComponent);
        }
      };
    },
  });
}

從上面的代碼可以看到defineAsyncComponent分為三部分。

  • 第一部分為:處理傳入的參數(shù)。
  • 第二部分為:load函數(shù)用于加載異步組件。
  • 第三部分為:返回defineComponent定義的組件。

第一部分:處理傳入的參數(shù)

我們看第一部分:處理傳入的參數(shù)。代碼如下:

function defineAsyncComponent(source) {
  if (isFunction(source)) {
    source = { loader: source };
  }
  const { loader, loadingComponent, errorComponent, delay = 200 } = source;
  let resolvedComp;
  // ...省略
}

首先使用isFunction(source)判斷傳入的source是不是函數(shù),如果是函數(shù),那么就將source重寫(xiě)為包含loader字段的對(duì)象:source = { loader: source }。然后使用const { loader, loadingComponent, errorComponent, delay = 200 } = source解構(gòu)出對(duì)應(yīng)的loading組件、加載失敗組件、延時(shí)時(shí)間。

看到這里我想你應(yīng)該明白了為什么defineAsyncComponent函數(shù)接收的參數(shù)可以是一個(gè)回調(diào)函數(shù),也可以是包含loader、loadingComponent、errorComponent等字段的對(duì)象。因?yàn)槿绻覀儌魅氲氖腔卣{(diào)函數(shù),在內(nèi)部會(huì)將傳入的回調(diào)函數(shù)賦值給loader字段。不過(guò)loading組件、加載失敗組件等參數(shù)不會(huì)有值,只有delay延時(shí)時(shí)間默認(rèn)給了200。

接著就是定義了load函數(shù)用于加載異步組件,這個(gè)函數(shù)是在第三部分的defineComponent中調(diào)用的,所以我們先來(lái)講defineComponent函數(shù)部分。

第三部分:返回defineComponent定義的組件

我們來(lái)看看defineAsyncComponent的返回值,是一個(gè)defineComponent定義的組件,代碼如下:

function defineAsyncComponent(source) {
  // ...省略

  return defineComponent({
    name: "AsyncComponentWrapper",
    setup() {
      const instance = currentInstance;
      const loaded = ref(false);
      const error = ref();
      const delayed = ref(!!delay);
      if (delay) {
        setTimeout(() => {
          delayed.value = false;
        }, delay);
      }
      load()
        .then(() => {
          loaded.value = true;
        })
        .catch((err) => {
          onError(err);
          error.value = err;
        });
      return () => {
        if (loaded.value && resolvedComp) {
          return createInnerComp(resolvedComp, instance);
        } else if (error.value && errorComponent) {
          return createVNode(errorComponent, {
            error: error.value,
          });
        } else if (loadingComponent && !delayed.value) {
          return createVNode(loadingComponent);
        }
      };
    },
  });
}

defineComponent函數(shù)的接收的參數(shù)是一個(gè)vue組件對(duì)象,返回值也是一個(gè)vue組件對(duì)象。他其實(shí)沒(méi)有做什么事情,單純的只是提供ts的類型推導(dǎo)。

我們接著來(lái)看vue組件對(duì)象,對(duì)象中只有兩個(gè)字段:name屬性和setup函數(shù)。

name屬性大家都很熟悉,表示當(dāng)前vue組件的名稱。

大家平時(shí)<script setup>語(yǔ)法糖用的比較多,這個(gè)語(yǔ)法糖經(jīng)過(guò)編譯后就是setup函數(shù),當(dāng)然vue也支持讓我們自己手寫(xiě)setup函數(shù)。

提個(gè)問(wèn)題:setup函數(shù)對(duì)應(yīng)的是<script setup>,我們平時(shí)寫(xiě)代碼都有template模塊對(duì)應(yīng)的是視圖部分,也就是熟悉的render函數(shù)。為什么這里沒(méi)有render函數(shù)呢?

給setup函數(shù)打個(gè)斷點(diǎn),當(dāng)渲染異步組件時(shí)會(huì)去執(zhí)行這個(gè)setup函數(shù)。代碼將會(huì)停留在setup函數(shù)的斷點(diǎn)處。

在setup函數(shù)中首先使用ref定義了三個(gè)響應(yīng)式變量:loaded、error、delayed。

  • loaded是一個(gè)布爾值,作用是記錄異步組件是否加載完成。
  • error記錄的是加載失敗時(shí)記錄的錯(cuò)誤信息,如果同時(shí)傳入了errorComponent組件,在加載異步組件失敗時(shí)就會(huì)顯示errorComponent組件。
  • delayed也是一個(gè)布爾值,由于loading組件不是立馬就顯示的,而是延時(shí)一段時(shí)間后再顯示。這個(gè)delayed布爾值記錄的是是當(dāng)前是否還在延時(shí)階段,如果是延時(shí)階段那么就不顯示loading組件。

接下來(lái)判斷傳入的參數(shù)中設(shè)置設(shè)置了delay延遲,如果是就使用setTimeout延時(shí)delay毫秒才將delayed的值設(shè)置為false,當(dāng)delayed的值為false后,在loading階段才會(huì)去顯示loading組件。代碼如下:

if (delay) {
  setTimeout(() => {
    delayed.value = false;
  }, delay);
}

接下來(lái)就是執(zhí)行l(wèi)oad函數(shù),這個(gè)load函數(shù)就是我們前面說(shuō)的defineAsyncComponent函數(shù)中的第二部分代碼。代碼如下:

load()
  .then(() => {
    loaded.value = true;
  })
  .catch((err) => {
    onError(err);
    error.value = err;
  });

從上面的代碼可以看到load函數(shù)明顯返回的是一個(gè)Promise,所以才可以在后面使用.then()和.catch()。并且這里在.then()中將loaded的值設(shè)置為true,將斷點(diǎn)走進(jìn)load函數(shù),代碼如下:

const load = () => {
  return loader()
    .catch(() => {
      // ...省略
    })
    .then((comp) => {
      if (
        comp &&
        (comp.__esModule || comp[Symbol.toStringTag] === "Module")
      ) {
        comp = comp.default;
      }
      resolvedComp = comp;
      return comp;
    });
};

這里的load函數(shù)代碼也很簡(jiǎn)單,在里面直接執(zhí)行l(wèi)oader函數(shù)。還記得這個(gè)loader函數(shù)是什么嗎?

defineAsyncComponent函數(shù)可以接收一個(gè)異步加載函數(shù),這個(gè)異步加載函數(shù)可以在運(yùn)行時(shí)去import導(dǎo)入組件。這個(gè)異步加載函數(shù)就是這里的loader函數(shù),執(zhí)行l(wèi)oader函數(shù)就會(huì)去加載異步組件。在我們這里是異步加載async-child.vue組件,代碼如下:

const AsyncChild = defineAsyncComponent(() => import("./async-child.vue"));

所以這里執(zhí)行l(wèi)oader函數(shù)就是在執(zhí)行() => import("./async-child.vue"),執(zhí)行了import()后就可以在network面板看到加載async-child.vue文件的網(wǎng)絡(luò)請(qǐng)求。import()返回的是一個(gè)Promise,等import的文件加載完了后就會(huì)觸發(fā)Promise的then(),所以這里的then()在此時(shí)不會(huì)觸發(fā)。

接著將斷點(diǎn)走出load函數(shù)回到setup函數(shù)的最后一個(gè)return部分,代碼如下:

setup() {
  // ...省略
  return () => {
    if (loaded.value && resolvedComp) {
      return createInnerComp(resolvedComp, instance);
    } else if (error.value && errorComponent) {
      return createVNode(errorComponent, {
        error: error.value,
      });
    } else if (loadingComponent && !delayed.value) {
      return createVNode(loadingComponent);
    }
  };
},

注意看,這里的setup的返回值是一個(gè)函數(shù),不是我們經(jīng)??匆?jiàn)的對(duì)象。由于這里返回的是函數(shù),此時(shí)代碼將不會(huì)走到返回的函數(shù)里面去,給return的函數(shù)打個(gè)斷點(diǎn)。我們暫時(shí)先不看函數(shù)中的內(nèi)容,讓斷點(diǎn)走出setup函數(shù)。發(fā)現(xiàn)setup函數(shù)是由vue中的setupStatefulComponent函數(shù)調(diào)用的,在我們這個(gè)場(chǎng)景中簡(jiǎn)化后的setupStatefulComponent函數(shù)代碼如下:

function setupStatefulComponent(instance) {
  const Component = instance.type;
  const { setup } = Component;
  const setupResult = callWithErrorHandling(setup, instance, 0, [
    instance.props,
    setupContext,
  ]);
  handleSetupResult(instance, setupResult);
}

上面的callWithErrorHandling函數(shù)從名字你應(yīng)該就能看出來(lái),調(diào)用一個(gè)函數(shù)并且進(jìn)行錯(cuò)誤處理。在這里就是調(diào)用setup函數(shù),然后將調(diào)用setup函數(shù)的返回值丟給handleSetupResult函數(shù)處理。

將斷點(diǎn)走進(jìn)handleSetupResult函數(shù),在我們這個(gè)場(chǎng)景中handleSetupResult函數(shù)簡(jiǎn)化后的代碼如下:

function handleSetupResult(instance, setupResult) {
  if (isFunction(setupResult)) {
    instance.render = setupResult;
  }
}

在前面我們講過(guò)了我們這個(gè)場(chǎng)景setup函數(shù)的返回值是一個(gè)函數(shù),所以isFunction(setupResult)的值為true。代碼將會(huì)走到instance.render = setupResult,這里的instance是當(dāng)前vue組件實(shí)例,執(zhí)行這個(gè)后就會(huì)將setupResult賦值給render函數(shù)。

我們知道render函數(shù)一般是由template模塊編譯而來(lái)的,執(zhí)行render函數(shù)就會(huì)生成虛擬DOM,最后由虛擬DOM生成對(duì)應(yīng)的真實(shí)DOM。

當(dāng)setup的返回值是一個(gè)函數(shù)時(shí),這個(gè)函數(shù)就會(huì)作為組件的render函數(shù)。這也就是為什么前面defineComponent中只有name熟悉和setup函數(shù),卻沒(méi)有render函數(shù)。

在執(zhí)行render函數(shù)生成虛擬DOM時(shí)就會(huì)去執(zhí)行setup返回的函數(shù),由于我們前面給返回的函數(shù)打了一個(gè)斷點(diǎn),所以代碼將會(huì)停留在setup返回的函數(shù)中?;仡櫼幌聅etup返回的函數(shù)代碼如下:

setup() {
  // ...省略
  return () => {
    if (loaded.value && resolvedComp) {
      return createInnerComp(resolvedComp, instance);
    } else if (error.value && errorComponent) {
      return createVNode(errorComponent, {
        error: error.value,
      });
    } else if (loadingComponent && !delayed.value) {
      return createVNode(loadingComponent);
    }
  };
},

由于此時(shí)還沒(méi)將異步組件加載完,所以loaded的值也是false,此時(shí)代碼不會(huì)走進(jìn)第一個(gè)if中。

同樣的組件都還沒(méi)加載完也不會(huì)有error,代碼也不會(huì)走到第一個(gè)else if中。

如果我們傳入了loading組件,此時(shí)代碼也不會(huì)走到第二個(gè)else if中。因?yàn)榇藭r(shí)的delayed的值還是true,代表還在延時(shí)階段。只有等到前面setTimeout的回調(diào)執(zhí)行后才會(huì)將delayed的值設(shè)置為false。

并且由于delayed是一個(gè)ref響應(yīng)式變量,所以在setTimeout的回調(diào)中改變了delayed的值就會(huì)重新渲染,也就是再次執(zhí)行render函數(shù)。前面講了這里的render函數(shù)就是setup中返回的函數(shù),代碼就會(huì)重新走到第二個(gè)else if中。

此時(shí)else if (loadingComponent && !delayed.value),其中的loadingComponent是loading組件,并且delayed.value的值也是false了。代碼就會(huì)走到createVNode(loadingComponent)中,執(zhí)行這個(gè)函數(shù)就會(huì)將loading組件渲染到頁(yè)面上。

加載異步組件

前面我們講過(guò)了在渲染異步組件時(shí)會(huì)執(zhí)行l(wèi)oad函數(shù),在里面其實(shí)就是執(zhí)行() => import("./async-child.vue")加載異步組件async-child.vue,我們也可以在network面板中看到多了一個(gè)async-child.vue文件的請(qǐng)求。

我們知道import()的返回值是一個(gè)Promise,當(dāng)文件加載完成后就會(huì)觸發(fā)Promise的then()。此時(shí)代碼將會(huì)走到第一個(gè)then()中,回憶一下代碼:

const load = () => {
  return loader()
    .catch(() => {
      // ...省略
    })
    .then((comp) => {
      if (
        comp &&
        (comp.__esModule || comp[Symbol.toStringTag] === "Module")
      ) {
        comp = comp.default;
      }
      resolvedComp = comp;
      return comp;
    });
};

在then()中判斷加載進(jìn)來(lái)的文件是不是一個(gè)es6的模塊,如果是就將模塊的default導(dǎo)出重寫(xiě)到comp組件對(duì)象中。并且將加載進(jìn)來(lái)的vue組件對(duì)象賦值給resolvedComp變量。

執(zhí)行完第一個(gè)then()后代碼將會(huì)走到第二個(gè)then()中,回憶一下代碼:

load()
  .then(() => {
    loaded.value = true;
  })

第二個(gè)then()代碼很簡(jiǎn)單,將loaded變量的值設(shè)置為true,也就是標(biāo)明已經(jīng)將異步組件加載完啦。由于loaded是一個(gè)響應(yīng)式變量,改變他的值就會(huì)導(dǎo)致頁(yè)面重新渲染,將會(huì)再次執(zhí)行render函數(shù)。前面我們講了這里的render函數(shù)就是setup中返回的函數(shù),代碼就會(huì)重新走到第二個(gè)else if中。

再來(lái)回顧一下setup中返回的函數(shù),代碼如下:

setup() {
  // ...省略
  return () => {
    if (loaded.value && resolvedComp) {
      return createInnerComp(resolvedComp, instance);
    } else if (error.value && errorComponent) {
      return createVNode(errorComponent, {
        error: error.value,
      });
    } else if (loadingComponent && !delayed.value) {
      return createVNode(loadingComponent);
    }
  };
},

由于此時(shí)loaded的值為true,并且resolvedComp的值為異步加載vue組件對(duì)象,所以這次render函數(shù)返回的虛擬DOM將是createInnerComp(resolvedComp, instance)的執(zhí)行結(jié)果。

createInnerComp函數(shù)

接著將斷點(diǎn)走進(jìn)createInnerComp函數(shù),在我們這個(gè)場(chǎng)景中簡(jiǎn)化后的代碼如下:

function createInnerComp(comp, parent) {
  const { ref: ref2, props, children } = parent.vnode;
  const vnode = createVNode(comp, props, children);
  vnode.ref = ref2;
  return vnode;
}

createInnerComp函數(shù)接收兩個(gè)參數(shù),第一個(gè)參數(shù)為要異步加載的vue組件對(duì)象。第二個(gè)參數(shù)為使用defineAsyncComponent創(chuàng)建的vue組件對(duì)應(yīng)的vue實(shí)例。

然后就是執(zhí)行createVNode函數(shù),這個(gè)函數(shù)大家可能有所耳聞,vue提供的h()函數(shù)其實(shí)就是調(diào)用的createVNode函數(shù)。

在我們這里createVNode函數(shù)接收的第一個(gè)參數(shù)為子組件對(duì)象,第二個(gè)參數(shù)為要傳給子組件的props,第三個(gè)參數(shù)為要傳給子組件的children。createVNode函數(shù)會(huì)根據(jù)這三個(gè)參數(shù)生成對(duì)應(yīng)的異步組件的虛擬DOM,將生成的異步組件的虛擬DOM進(jìn)行return返回,最后就是根據(jù)虛擬DOM生成真實(shí)DOM將異步組件渲染到頁(yè)面上。如下圖(圖后還有一個(gè)總結(jié)):

圖片圖片

總結(jié)

本文講了defineAsyncComponent是如何實(shí)現(xiàn)異步組件的:

  • 在defineAsyncComponent函數(shù)中會(huì)返回一個(gè)vue組件對(duì)象,對(duì)象中只有name屬性和setup函數(shù)。
  • 當(dāng)渲染異步組件時(shí)會(huì)執(zhí)行setup函數(shù),在setup函數(shù)中會(huì)執(zhí)行內(nèi)置的一個(gè)load方法。在load方法中會(huì)去執(zhí)行由defineAsyncComponent定義的異步組件加載函數(shù),這個(gè)加載函數(shù)的返回值是一個(gè)Promise,異步組件加載完成后就會(huì)觸發(fā)Promise的then()。
  • 在setup函數(shù)中會(huì)返回一個(gè)函數(shù),這個(gè)函數(shù)將會(huì)是組件的render函數(shù)。
  • 當(dāng)異步組件加載完了后會(huì)走到前面說(shuō)的Promise的then()方法中,在里面會(huì)將loaded響應(yīng)式變量的值修改為true。
  • 修改了響應(yīng)式變量的值導(dǎo)致頁(yè)面重新渲染,然后執(zhí)行render函數(shù)。前面講過(guò)了此時(shí)的render函數(shù)是setup函數(shù)中會(huì)返回的回調(diào)函數(shù)。執(zhí)行這個(gè)回調(diào)函數(shù)會(huì)調(diào)用createInnerComp函數(shù)生成異步組件的虛擬DOM,最后就是根據(jù)虛擬DOM生成真實(shí)DOM,從而將異步子組件渲染到頁(yè)面上。
責(zé)任編輯:武曉燕 來(lái)源: 前端歐陽(yáng)
相關(guān)推薦

2021-05-18 07:51:37

Suspense組件Vue3

2021-09-29 11:33:19

異步組件Vue 3

2021-12-02 05:50:35

Vue3 插件Vue應(yīng)用

2024-08-07 10:16:00

2024-03-13 08:37:18

Vue3Suspense異步組件

2021-08-01 07:58:58

Vue 加載組件

2024-01-23 09:15:33

Vue3組件拖拽組件內(nèi)容編輯

2020-12-01 08:34:31

Vue3組件實(shí)踐

2022-01-19 18:05:47

Vue3前端代碼

2022-07-27 08:40:06

父子組件VUE3

2023-04-02 10:06:24

組件vue3sign2.

2023-11-28 09:03:59

Vue.jsJavaScript

2024-02-01 09:10:04

頁(yè)面引導(dǎo)工具Vue3

2024-01-08 08:50:19

Vue3級(jí)聯(lián)菜單數(shù)據(jù)懶加載

2023-04-27 11:07:24

Setup語(yǔ)法糖Vue3

2024-05-28 08:02:08

Vue3父組件子組件

2022-09-20 11:00:14

Vue3滾動(dòng)組件

2024-03-21 08:34:49

Vue3WebSocketHTTP

2022-03-10 11:04:04

Vue3Canvas前端

2024-07-30 08:59:22

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)