<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          組件的拆分粒度是越細(xì)越好嗎

          共 2826字,需瀏覽 6分鐘

           ·

          2021-08-05 11:37

          點擊上方 程序員成長指北,關(guān)注公眾號

          回復(fù)1,加入高級Node交流群


          Hello,各位小伙伴,接下來的一段時間里,我會把我的課程《Vue.js 3.0 核心源碼解析》中問題的答案陸續(xù)在我的公眾號發(fā)布,由于課程的問題大多數(shù)都是開放性的問題,所以我的答案也不一定是標(biāo)準(zhǔn)的,僅供你參考喔。

          那么,回到這個問題本身,組件的拆分粒度是越細(xì)越好嗎?先說結(jié)論:并不是。為什么呢?

          什么是組件

          組件是一個抽象的概念,它是對一棵 DOM 樹的抽象,直觀點說,一個組件可以包含若干個原生 DOM 標(biāo)簽,舉個例子,假設(shè)我們有一個 HelloWorld 組件,如下:

          <template>
            <div>
              <p>Hello World</p>
            </div>
          </template>

          然后我們在頁面中去引用這個組件:

          <hello-world></hello-world>

          這段代碼并不會在頁面上渲染一個 <hello-world> 標(biāo)簽,而是會渲染 HelloWorld 組件中的模板內(nèi)容,即渲染一個 div,內(nèi)部包含一個 p 標(biāo)簽,顯示 Hello World 文本。

          當(dāng)然,組件除了對 DOM 層面的封裝,還可以對數(shù)據(jù)、邏輯、交互等等進(jìn)行封裝,不僅如此,組件還支持嵌套,所以整個頁面就是可以由一個個嵌套的組件構(gòu)成,抽象成一棵組件樹,如下:

          組件化是 Vue.js 的核心思想之一,它允許我們用模板加對象描述的方式去創(chuàng)建一個組件,再加上我們給組件注入不同的數(shù)據(jù),就可以完整地渲染出組件,那么它具體是怎么做的呢?

          組件是如何渲染的

          眾所周知,Vue.js 對開發(fā)者非常友好的一點是支持模板,任何合乎規(guī)范的 HTML 都是合法的 Vue 模板。Vue.js 對于模板會有一個編譯的過程(可以離線完成,也可以在運行時完成),Vue.js 在編譯模板的過程中會識別出組件標(biāo)簽,編譯生成對應(yīng)的 render 函數(shù)。

          你可以借助 Vue.js 的在線模板編譯工具看一下我們前面示例 <hello-world></hello-world> 的編譯結(jié)果:

          import { resolveComponent as _resolveComponent, createVNode as _createVNode, openBlock as _openBlock, createBlock as _createBlock } from "vue"

          export function render(_ctx, _cache, $props, $setup, $data, $options{
            const _component_hello_world = _resolveComponent("hello-world")

            return (_openBlock(), _createBlock(_component_hello_world))
          }

          首先,它會解析出對應(yīng)的組件定義對象,然后根據(jù)這個組件對象創(chuàng)建一個組件的 vnode。

          創(chuàng)建完 vnode 后,在 Vue.js 內(nèi)部會執(zhí)行 patch 方法渲染這個 vnode,最終創(chuàng)建生成 DOM 并在頁面中渲染。所以單個組件的渲染過程大致如下:

          前面說過,組件是支持嵌套的,所以整個組件樹的掛載過程,就是一個遞歸掛載組件的過程。

          在組件的掛載過程中,除了前面說的創(chuàng)建和渲染 vnode 之外,內(nèi)部還創(chuàng)建了一個組件實例,用來維護(hù)組件的狀態(tài)和數(shù)據(jù),此外,還有組件初始化階段的一些響應(yīng)式數(shù)據(jù)處理,這些都是有一定耗時和內(nèi)存占用的。

          因此,如果我們拆分組件的粒度過細(xì),會導(dǎo)致嵌套組件過深,顯而易見的是整個應(yīng)用的初始化時長會變長,占用的內(nèi)存空間也會變大。

          如何拆分組件

          那么,我們該如何拆分組件呢?其實組件的拆分通常有兩種場景。

          • 基礎(chǔ)組件

          主要是指可復(fù)用,實現(xiàn)某類功能,且不包含任何業(yè)務(wù)的組件,比如像 ElementUI 這樣的組件庫,提供的就是基礎(chǔ)組件庫,包含幾十種不同功能的基礎(chǔ)組件。

          但是基礎(chǔ)組件并不一定是單一組件,它可以是一個復(fù)合組件,由若干更小的組件單元甚至是其它基礎(chǔ)組件組成。比如 Table 組件,它內(nèi)部就是由 HeaderBody 組件組成,而 Body 組件,內(nèi)部又是通過循環(huán)渲染 Cell 組件組成。

          有了基礎(chǔ)組件庫可以幫助你統(tǒng)一視覺規(guī)范,也會大大提升你的工作效率。

          所以在日常開發(fā)工作中,如果沒有條件你就直接依賴開源的第三方組件庫開發(fā),有條件的話建議你在這些優(yōu)秀的開源組件庫基礎(chǔ)上,自研一套適合自身業(yè)務(wù)的組件庫。

          • 業(yè)務(wù)組件

          業(yè)務(wù)組件是在基礎(chǔ)組件的基礎(chǔ)上,開發(fā)出的融入業(yè)務(wù)邏輯的復(fù)合組件,通常,業(yè)務(wù)組件是為了解決某個特定的業(yè)務(wù)場景,它的復(fù)用性相比于基礎(chǔ)組件而言,沒有那么的強(qiáng)。

          不過,業(yè)務(wù)組件也是可以復(fù)用的。比如彈窗登錄的場景,就有一套完整的業(yè)務(wù)邏輯以及和服務(wù)端的交互流程,我們可以把它拆成一個登錄組件,這樣就可以在頁面中方便的接入和復(fù)用。

          在日常開發(fā)工作中,你要經(jīng)常思考,能不能把某類場景的業(yè)務(wù)抽象成業(yè)務(wù)組件,因為隨著業(yè)務(wù)組件的積累,工作效率也會得到明顯的提升。

          因此,拆分組件主要是從代碼的復(fù)用性和維護(hù)性方面考慮,另外,從性能方面考慮,組件拆分粒度不易過細(xì)。

          總結(jié)

          我出這個題的主要希望你能做到以下兩點:

          1. 從源碼層面分析,你需要知道組件的初始化過程有哪些代價。

          2. 從應(yīng)用層面思考,你需要知道如何去抽象和拆分組件。

          要記住,分析和思考的過程遠(yuǎn)比答案重要。

          如果覺得這篇文章還不錯
          點擊下面卡片關(guān)注我
          來個【分享、點贊、在看】三連支持一下吧

             “分享、點贊在看” 支持一波 

          瀏覽 112
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产在线欧美日韩字幕 | 亚洲小穴 | 成人性生交大片免费看黄106季 | 三级国产三级在线 | 午夜三级福利无码 |