日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Vue3.0進(jìn)階之應(yīng)用掛載的過程之一

本文轉(zhuǎn)載自微信公眾號「全棧修仙之路」,作者阿寶哥。轉(zhuǎn)載本文請聯(lián)系全棧修仙之路公眾號。  

 本文是 Vue 3.0 進(jìn)階系列 的第八篇文章,在這篇文章中,阿寶哥將帶大家一起探索 Vue 3 中應(yīng)用掛載的過程。在開始介紹應(yīng)用掛載的過程之前,我們先來簡單回顧一下第七篇介紹的 應(yīng)用創(chuàng)建的過程:

一、應(yīng)用掛載

在創(chuàng)建完 app 對象之后,就會調(diào)用 app.mount 方法執(zhí)行應(yīng)用掛載操作:

 
 
 
 
 
  •  
  • 雖然 app.mount 方法用起來很簡單,但它內(nèi)部涉及的處理邏輯還是蠻復(fù)雜的。這里阿寶哥利用 Chrome 開發(fā)者工具的 Performance 標(biāo)簽欄,記錄了應(yīng)用掛載的主要過程:

    接下來,阿寶哥就會以前面的示例為例,來詳細(xì)分析一下應(yīng)用掛載過程中涉及的主要函數(shù)。

    1.1 app.mount

    app.mount 被定義在 runtime-dom/src/index.ts 文件中,具體實(shí)現(xiàn)如下所示:

     
     
     
     
    1. // packages/runtime-dom/src/index.ts 
    2. app.mount = (containerOrSelector: Element | ShadowRoot | string): any => { 
    3.   const container = normalizeContainer(containerOrSelector) // ① 同時支持字符串和DOM對象 
    4.   if (!container) return 
    5.   const component = app._component 
    6.   // 若根組件非函數(shù)對象且未設(shè)置render和template屬性,則使用容器的innerHTML作為模板的內(nèi)容 
    7.   if (!isFunction(component) && !component.render && !component.template) { // ② 
    8.     component.template = container.innerHTML 
    9.   } 
    10.   container.innerHTML = ''  // 在掛載前清空容器內(nèi)容 
    11.   const proxy = mount(container, false, container instanceof SVGElement) // ③ 
    12.   if (container instanceof Element) { 
    13.     container.removeAttribute('v-cloak') // 避免在網(wǎng)絡(luò)不好或加載數(shù)據(jù)過大的情況下,頁面渲染的過程中會出現(xiàn)Mustache標(biāo)簽 
    14.     container.setAttribute('data-v-app', '') 
    15.   } 
    16.   return proxy 

    在 app.mount 方法內(nèi)部主要分為以下 3 個流程:

    • 規(guī)范化容器,normalizeContainer 函數(shù)參數(shù) container 的類型是一個聯(lián)合類型:Element | ShadowRoot | string,如果傳入?yún)?shù)是字符串類型的話,會通過 document.querySelector API 來獲取選擇器對應(yīng)的 DOM 元素。而對于其他類型的話,會直接返回傳入的參數(shù)。
    • 設(shè)置根組件的 template 屬性,當(dāng)根組件不是函數(shù)組件且根組件配置對象上沒有 render 和 template 屬性,則會使用容器元素上 innerHTML 的值作為根組件 template 屬性的屬性值。
    • 調(diào)用 mount 方法執(zhí)行真正的掛載操作。

    1.2 mount

    對于 app.mount 方法來說,最核心的流程是 mount 方法,所以下一步我們就來分析 mount 方法。

     
     
     
     
    1. // packages/runtime-core/src/apiCreateApp.ts 
    2. export function createAppAPI
    3.   render: RootRenderFunction, 
    4.   hydrate?: RootHydrateFunction 
    5. ): CreateAppFunction { 
    6.   return function createApp(rootComponent, rootProps = null) { 
    7.     const app: App = (context.app = { 
    8.       _container: null, 
    9.       _context: context, 
    10.      // 省略部分代碼 
    11.        
    12.       mount( 
    13.         rootContainer: HostElement, 
    14.         isHydrate?: boolean, 
    15.         isSVG?: boolean 
    16.       ): any { 
    17.         if (!isMounted) { 
    18.           const vnode = createVNode( // ① 創(chuàng)建根組件對應(yīng)的VNode對象 
    19.             rootComponent as ConcreteComponent, 
    20.             rootProps 
    21.           ) 
    22.           vnode.appContext = context // ② 設(shè)置VNode對象上的應(yīng)用上下文屬性 
    23.      // 省略部分代碼 
    24.           if (isHydrate && hydrate) { 
    25.             hydrate(vnode as VNode, rootContainer as any) 
    26.           } else {  
    27.             render(vnode, rootContainer, isSVG) // ③ 執(zhí)行渲染操作 
    28.           } 
    29.           isMounted = true 
    30.           app._container = rootContainer 
    31.           ;(rootContainer as any).__vue_app__ = app 
    32.           return vnode.component!.proxy 
    33.         } 
    34.       }, 
    35.     }) 
    36.  
    37.     return app 
    38.   } 

    1.3 render

    觀察以上的 mount 函數(shù)可知,在 mount 方法內(nèi)部會調(diào)用繼續(xù)調(diào)用 render 函數(shù)執(zhí)行渲染操作,該函數(shù)的具體實(shí)現(xiàn)如下:

     
     
     
     
    1. const render: RootRenderFunction = (vnode, container) => { 
    2.   if (vnode == null) { 
    3.     if (container._vnode) { 
    4.       unmount(container._vnode, null, null, true) 
    5.     } 
    6.   } else { 
    7.       patch(container._vnode || null, vnode, container) 
    8.   } 
    9.   flushPostFlushCbs() 
    10.   container._vnode = vnode 

    對于首次渲染來說,此時的 vnode 不為 null(基于根組件創(chuàng)建的 VNode 對象),所以會執(zhí)行 else 分支的流程,即調(diào)用 patch 函數(shù)。

    1.4 patch

    patch 函數(shù)被定義在 runtime-core/src/renderer.ts 文件中,該函數(shù)的簽名如下所示:

     
     
     
     
    1. // packages/runtime-core/src/renderer.ts 
    2. const patch: PatchFn = ( 
    3.     n1, // old VNode 
    4.     n2, // new VNode 
    5.     container, 
    6.     anchor = null, 
    7.     parentComponent = null, 
    8.     parentSuspense = null, 
    9.     isSVG = false, 
    10.     slotScopeIds = null, 
    11.     optimized = false 
    12. ) => { //...} 

    在 patch 函數(shù)內(nèi)部,會根據(jù) VNode 對象的類型執(zhí)行不同的處理邏輯:

    在上圖中,我們看到了 Text、Comment 、Static 和 Fragment 這些類型,它們的定義如下:

     
     
     
     
    1. // packages/runtime-core/src/vnode.ts 
    2. export const Text = Symbol(__DEV__ ? 'Text' : undefined) 
    3. export const Comment = Symbol(__DEV__ ? 'Comment' : undefined) 
    4. export const Static = Symbol(__DEV__ ? 'Static' : undefined) 
    5. export const Fragment = (Symbol(__DEV__ ? 'Fragment' : undefined) as any) as { 
    6.   __isFragment: true 
    7.   new (): { 
    8.     $props: VNodeProps 
    9.   } 

    除了上述的類型之外,在 default 分支,我們還看到了 ShapeFlags,該對象是一個枚舉:

     
     
     
     
    1. // packages/shared/src/shapeFlags.ts 
    2. export const enum ShapeFlags { 
    3.   ELEMENT = 1, 
    4.   FUNCTIONAL_COMPONENT = 1 << 1, 
    5.   STATEFUL_COMPONENT = 1 << 2, 
    6.   TEXT_CHILDREN = 1 << 3, 
    7.   ARRAY_CHILDREN = 1 << 4, 
    8.   SLOTS_CHILDREN = 1 << 5, 
    9.   TELEPORT = 1 << 6, 
    10.   SUSPENSE = 1 << 7, 
    11.   COMPONENT_SHOULD_KEEP_ALIVE = 1 << 8, 
    12.   COMPONENT_KEPT_ALIVE = 1 << 9, 
    13.   COMPONENT = ShapeFlags.STATEFUL_COMPONENT | ShapeFlags.FUNCTIONAL_COMPONENT 

    那么 ShapeFlags 標(biāo)志是什么時候設(shè)置的呢?其實(shí)在創(chuàng)建 VNode 對象時,就會設(shè)置該對象的 shapeFlag 屬性,對應(yīng)的判斷規(guī)則如下所示:

     
     
     
     
    1. // packages/runtime-core/src/vnode.ts 
    2. function _createVNode( 
    3.   type: VNodeTypes | ClassComponent | typeof NULL_DYNAMIC_COMPONENT, 
    4.   props: (Data & VNodeProps) | null = null, 
    5.   children: unknown = null, 
    6.   patchFlag: number = 0, 
    7.   dynamicProps: string[] | null = null, 
    8.   isBlockNode = false 
    9. ): VNode { 
    10.   // 省略大部分方法 
    11.   const shapeFlag = isString(type)// 字符串類型 
    12.     ? ShapeFlags.ELEMENT 
    13.     : __FEATURE_SUSPENSE__ && isSuspense(type) // SUSPENSE類型 
    14.       ? ShapeFlags.SUSPENSE 
    15.       : isTeleport(type) // TELEPORT類型 
    16.         ? ShapeFlags.TELEPORT 
    17.         : isObject(type) // 對象類型 
    18.           ? ShapeFlags.STATEFUL_COMPONENT 
    19.           : isFunction(type) // 函數(shù)類型 
    20.             ? ShapeFlags.FUNCTIONAL_COMPONENT 
    21.             : 0 
    22.  
    23.   const vnode: VNode = { 
    24.     __v_isVNode: true, 
    25.     [ReactiveFlags.SKIP]: true, 
    26.   // 省略大部分屬性 
    27.     shapeFlag, 
    28.     appContext: null 
    29.   } 
    30.   normalizeChildren(vnode, children) 
    31.   return vnode 

    1.5 processComponent

    由以上代碼可知,對于我們示例來說,根組件對應(yīng)的 VNode 對象上 shapeFlag 的值為 ShapeFlags.STATEFUL_COMPONENT。因此,在執(zhí)行 patch 方法時,將會調(diào)用 processComponent 函數(shù):

     
     
     
     
    1. // packages/runtime-core/src/renderer.ts   
    2. const processComponent = ( 
    3.   n1: VNode | null,  
    4.   n2: VNode, 
    5.   container: RendererElement, 
    6.   anchor: RendererNode | null, 
    7.   parentComponent: ComponentInternalInstance | null, 
    8.   parentSuspense: SuspenseBoundary | null, 
    9.   isSVG: boolean, optimized: boolean 
    10.   ) => { 
    11.     if (n1 == null) { // 首次渲染 
    12.       if (n2.shapeFlag & ShapeFlags.COMPONENT_KEPT_ALIVE) { 
    13.         // 處理keep-alive組件 
    14.       } else { 
    15.         mountComponent( 
    16.           n2, container, anchor, 
    17.           parentComponent, parentSuspense, 
    18.           isSVG, optimized 
    19.         ) 
    20.       } 
    21.     } else { // 更新操作 
    22.       updateComponent(n1, n2, optimized) 
    23.     } 

    1.6 mountComponent

    對于首次渲染的場景,n1 的值為 null,我們的組件又不是 keep-alive 組件,所以會調(diào)用 mountComponent 函數(shù)掛載組件:

     
     
     
     
    1. // packages/runtime-core/src/renderer.ts   
    2. const mountComponent: MountComponentFn = ( 
    3.   initialVNode, container, anchor,  
    4.   parentComponent, parentSuspense, isSVG, optimized 
    5. ) => { 
    6.     // 省略部分代碼 
    7.     // ① 創(chuàng)建組件實(shí)例 
    8.     const instance: ComponentInternalInstance = (initialVNode.component = createComponentInstance( 
    9.       initialVNode, parentComponent, parentSuspense 
    10.     )) 
    11.     // ② 初始化組件實(shí)例 
    12.     setupComponent(instance) 
    13.     // ③ 設(shè)置渲染副作用函數(shù) 
    14.     setupRenderEffect( 
    15.       instance, initialVNode, container, 
    16.       anchor, parentSuspense, isSVG, optimized 
    17.     ) 

    在 mountComponent 函數(shù)內(nèi)部,主要含有 3 個步驟:

    • 調(diào)用 createComponentInstance 函數(shù)創(chuàng)建組件實(shí)例;
    • 調(diào)用 setupComponent 函數(shù)初始化組件實(shí)例;
    • 調(diào)用 setupRenderEffect 函數(shù),設(shè)置渲染副作用函數(shù)。

    1.7 createComponentInstance

    下面我們將會逐一分析上述的 3 個步驟:

     
     
     
     
    1. // packages/runtime-core/src/component.ts 
    2. export function createComponentInstance( 
    3.   vnode: VNode, 
    4.   parent: ComponentInternalInstance | null, 
    5.   suspense: SuspenseBoundary | null 
    6. ) { 
    7.   const type = vnode.type as ConcreteComponent 
    8.   // inherit parent app context - or - if root, adopt from root vnode 
    9.   const appContext = 
    10.     (parent ? parent.appContext : vnode.appContext) || emptyAppContext 
    11.  
    12.   const instance: ComponentInternalInstance = { // 創(chuàng)建組件實(shí)例 
    13.     uid: uid++, vnode, type, parent, appContext, 
    14.     root: null!, next: null, subTree: null!, update: null!,  
    15.     render: null, proxy: null, exposed: null, withProxy: null, effects: null, 
    16.     provides: parent ? parent.provides : Object.create(appContext.provides), 
    17.     // ...  
    18.   } 
    19.    
    20.   if (__DEV__) { 
    21.     instance.ctx = createRenderContext(instance) 
    22.   } else { 
    23.     instance.ctx = { _: instance } // 設(shè)置實(shí)例上的上下文屬性ctx 
    24.   } 
    25.   instance.root = parent ? parent.root : instance 
    26.   instance.emit = emit.bind(null, instance) // 設(shè)置emit屬性,用于派發(fā)自定義事件 
    27.  
    28.   return instance 

    調(diào)用 createComponentInstance 函數(shù)后,會返回一個包含了多種屬性的組件實(shí)例對象。

    1.8 setupComponent

    此外,在創(chuàng)建完組件實(shí)例后,會調(diào)用 setupComponent 函數(shù)執(zhí)行組件初始化操作:

     
     
     
     
    1. // packages/runtime-core/src/component.ts 
    2. export function setupComponent( 
    3.   instance: ComponentInternalInstance, 
    4.   isSSR = false 
    5. ) { 
    6.   isInSSRComponentSetup = isSSR 
    7.   const { props, children } = instance.vnode 
    8.   const isStateful = isStatefulComponent(instance) // 判斷是否狀態(tài)組件 
    9.   initProps(instance, props, isStateful, isSSR) // 初始化props屬性 
    10.   initSlots(instance, children) // 初始化slots 
    11.  
    12.   const setupResult = isStateful 
    13.     ? setupStatefulComponent(instance, isSSR) // 初始化有狀態(tài)組件 
    14.     : undefined 
    15.   isInSSRComponentSetup = false 
    16.   return setupResult 

    在 setupComponent 函數(shù)中,會分別調(diào)用 initProps 和 initSlots 函數(shù)來初始化組件實(shí)例的 props 屬性和 slots 屬性。之后會通過 isStatefulComponent 函數(shù)來判斷組件的類型:

     
     
     
     
    1. // packages/runtime-core/src/component.ts 
    2. export function isStatefulComponent(instance: ComponentInternalInstance) { 
    3.   return instance.vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT 
    4.  
    5. // 在createVNode函數(shù)內(nèi)部,會根據(jù)組件的type類型設(shè)置ShapeFlags標(biāo)識 
    6. const shapeFlag = isString(type) 
    7.     ? ShapeFlags.ELEMENT 
    8.     : __FEATURE_SUSPENSE__ && isSuspense(type) 
    9.       ? ShapeFlags.SUSPENSE 
    10.       : isTeleport(type) 
    11.         ? ShapeFlags.TELEPORT 
    12.         : isObject(type) // ComponentOptions 類型 
    13.           ? ShapeFlags.STATEFUL_COMPONENT 
    14.           : isFunction(type) // 函數(shù)式組件 
    15.             ? ShapeFlags.FUNCTIONAL_COMPONENT 
    16.             : 0 

    很明顯,如果 type 是對象類型,則組件是有狀態(tài)組件。而如果 type 是函數(shù)類型的話,則組件是函數(shù)組件。

    1.9 setupStatefulComponent

    對于有狀態(tài)組件來說,還會繼續(xù)調(diào)用 setupStatefulComponent 函數(shù)來初始化有狀態(tài)組件:

     
     
     
     
    1. // packages/runtime-core/src/component.ts 
    2. function setupStatefulComponent( 
    3.   instance: ComponentInternalInstance, 
    4.   isSSR: boolean 
    5. ) { 
    6.   const Component = instance.type as ComponentOptions // 組件配置對象 
    7.    
    8.   // 0. create render proxy property access cache 
    9.   instance.accessCache = Object.create(null) 
    10.   // 1. create public instance / render proxy 
    11.   // also mark it raw so it's never observed 
    12.   instance.proxy = new Proxy(instance.ctx, PublicInstanceProxyHandlers) // instance.ctx = { _: instance } 
    13.   // 2. call setup() 
    14.   const { setup } = Component // 組合式API中配置的setup函數(shù) 
    15.   if (setup) { 
    16.     // 處理組合式API的setup函數(shù) 
    17.   } else { 
    18.     finishComponentSetup(instance, isSSR) 
    19.   } 

    在 setupStatefulComponent 函數(shù)內(nèi)部,主要也可以分為 3 個步驟:

    • 在組件實(shí)例上設(shè)置 accessCache 屬性,即創(chuàng)建 render proxy 屬性的訪問緩存;
    • 使用 Proxy API 設(shè)置組件實(shí)例的 render proxy 屬性;
    • 判斷組件配置對象上是否設(shè)置了 setup 屬性,如果當(dāng)前組件配置對象不包含 setup 屬性,則會走 else 分支,即調(diào)用 finishComponentSetup 函數(shù)。

    接下來,我們來重點(diǎn)分析后面 2 個步驟。首先,我們先來分析 instance.proxy 屬性。如果你對 Proxy API 不了解的話,可以看一下 你不知道的 Proxy 這篇文章。至于 proxy 屬性有什么的作用,阿寶哥將在后續(xù)的文章中介紹。下面我們來回顧一下 Proxy 構(gòu)造函數(shù):

     
     
     
     
    1. const p = new Proxy(target, handler) 

    Proxy 構(gòu)造函數(shù)支持兩個參數(shù):

    • target:要使用 Proxy 包裝的目標(biāo)對象(可以是任何類型的對象,包括原生數(shù)組,函數(shù),甚至另一個代理)。
    • handler:一個通常以函數(shù)作為屬性的對象,各屬性中的函數(shù)分別定義了在執(zhí)行各種操作時代理 p 的行為。

    對于 setupStatefulComponent 函數(shù)來說,target 參數(shù)指向的是組件實(shí)例 ctx 屬性,即 { _: instance } 對象。而 handler 參數(shù)指向的是 PublicInstanceProxyHandlers 對象,該對象內(nèi)部包含了 3 種類型的捕捉器:

     
     
     
     
    1. // vue-next/packages/runtime-core/src/componentPublicInstance.ts 
    2. export const PublicInstanceProxyHandlers: ProxyHandler = { 
    3.   // 屬性讀取操作的捕捉器。 
    4.   get({ _: instance }: ComponentRenderContext, key: string) { 
    5.     // ... 
    6.   }, 
    7.   // 屬性設(shè)置操作的捕捉器。 
    8.   set( 
    9.     { _: instance }: ComponentRenderContext, 
    10.     key: string, 
    11.     value: any 
    12.   ): boolean { 
    13.     // ... 
    14.   }, 
    15.   // in 操作符的捕捉器。 
    16.   has( 
    17.     { 
    18.       _: { data, setupState, accessCache, ctx, appContext, propsOptions } 
    19.     }: ComponentRenderContext, 
    20.     key: string 
    21.   ) { 
    22.    // ... 
    23.   } 

    這里我們只要先知道 PublicInstanceProxyHandlers 對象中,包含了 get、set 和 has 這 3 種類型的捕捉器即可。至于捕捉器的內(nèi)部處理邏輯,阿寶哥將在 Vue 3.0 進(jìn)階之應(yīng)用掛載的過程下篇 中詳細(xì)介紹。

    1.10 finishComponentSetup

    在設(shè)置好 instance.proxy 屬性之后,會判斷組件配置對象上是否設(shè)置了 setup 屬性。對于前面的示例來說,會走 else 分支,即調(diào)用 finishComponentSetup 函數(shù),該函數(shù)的具體實(shí)現(xiàn)如下:

     
     
     
     
    1. // packages/runtime-core/src/component.ts 
    2. function finishComponentSetup( 
    3.   instance: ComponentInternalInstance, 
    4.   isSSR: boolean 
    5. ) { 
    6.   const Component = instance.type as ComponentOptions 
    7.   // template / render function normalization 
    8.   if (__NODE_JS__ && isSSR) { // 服務(wù)端渲染的場景 
    9.     if (Component.render) { 
    10.       instance.render = Component.render as InternalRenderFunction 
    11.     } 
    12.   } else if (!instance.render) { // 組件實(shí)例中不包含render方法 
    13.     // could be set from setup() 
    14.     if (compile && Component.template && !Component.render) { 
    15.       // 編譯組件的模板生成渲染函數(shù) 
    16.       Component.render = compile(Component.template, { 
    17.         isCustomElement: instance.appContext.config.isCustomElement, 
    18.         delimiters: Component.delimiters 
    19.       }) 
    20.     } 
    21.     // 把渲染函數(shù)添加到instance實(shí)例的render屬性中 
    22.     instance.render = (Component.render || NOOP) as InternalRenderFunction 
    23.     // for runtime-compiled render functions using `with` blocks, the render 
    24.     // proxy used needs a different `has` handler which is more performant and 
    25.     // also only allows a whitelist of globals to fallthrough. 
    26.     if (instance.render._rc) { 
    27.       instance.withProxy = new Proxy( 
    28.         instance.ctx, 
    29.         RuntimeCompiledPublicInstanceProxyHandlers 
    30.       ) 
    31.     } 
    32.   } 

    在分析 finishComponentSetup 函數(shù)前,我們來回顧一下示例中的代碼:

     
     
     
     
    1. const app = createApp({ 
    2.   data() { 
    3.     return { 
    4.       name: '我是阿寶哥' 
    5.     } 
    6.   }, 
    7.   template: `
      大家好, {{name}}!
    8. }) 

    對于該示例而言,根組件配置對象并沒有設(shè)置 render 屬性。而且阿寶哥引入的是包含編譯器的 vue.global.js 文件,所以會走 else if 分支。即會調(diào)用 compile 函數(shù)來對模板進(jìn)行編譯。那么編譯后會生成什么呢?通過斷點(diǎn),我們可以輕易地看到模板編譯后生成的渲染函數(shù):

     
     
     
     
    1. (function anonymous() { 
    2. const _Vue = Vue 
    3.  
    4. return function render(_ctx, _cache) { 
    5.   with (_ctx) { 
    6.     const { toDisplayString: _toDisplayString, createVNode: _createVNode,  
    7.       openBlock: _openBlock, createBlock: _createBlock } = _Vue 
    8.     return (_openBlock(), _createBlock("div", null, "大家好, " + _toDisplayString(name) + "!", 1)) 
    9.   } 
    10. }) 

    觀察以上的代碼可知,調(diào)用渲染函數(shù)之后會返回 createBlock 函數(shù)的調(diào)用結(jié)果,即 VNode 對象。另外,在 render 函數(shù)中,會通過 with 來設(shè)置渲染上下文。那么該渲染函數(shù)什么時候會被調(diào)用呢?對于這個問題,感興趣的小伙伴可以先自行研究一下。

    出于篇幅考慮,阿寶哥把應(yīng)用掛載的過程分為上下兩篇,在下一篇文章中阿寶哥將重點(diǎn)介紹 setupRenderEffect 函數(shù)。介紹完該函數(shù)之后,你將會知道渲染函數(shù)什么時候會被調(diào)用,到時候也會涉及響應(yīng)式 API 的一些相關(guān)知識,對這部分內(nèi)容還不熟悉的小伙伴可以先看看 Vue 3 的官方文檔。

    最后,阿寶哥用一張流程圖來總結(jié)一下本文介紹的主要內(nèi)容:

    本文主要介紹了在 Vue 3 中組件掛載過程中涉及的一些核心函數(shù),出于篇幅考慮,阿寶哥只介紹其中的一部分函數(shù)。此外,為了讓大家能夠更深入地理解 App 掛載的過程,阿寶哥從源碼的角度分析了核心函數(shù)中的主要處理邏輯。

    在下一篇文章中,阿寶哥將會繼續(xù)介紹應(yīng)用掛載過程中剩余的內(nèi)容,同時也會解答本文留下的問題,感興趣的小伙伴請繼續(xù)關(guān)注下一篇文章。

    二、參考資源

    • MDN - Proxy
    • Vue 3 官網(wǎng) - 應(yīng)用 API

    當(dāng)前文章:Vue3.0進(jìn)階之應(yīng)用掛載的過程之一
    地址分享:http://www.dlmjj.cn/article/cogdico.html