[譯] 複用 Vue 組件的 6 層手段

原文:michaelnthiessen.com/6-levels-of…html

在編寫代碼的時候,誰都想「少幹活、多辦事」。以組件而言,咱們但願它能被不止一次地複用。前端

一些組件僅需基本的複用性。vue

另外一些則須要更復雜的技術以充分利用。svg

我認爲複用性有 6 中不一樣的層級,這裏大致上來看一下:組件化

1. 模版化

不一樣於將代碼隨處複製/粘貼的是,藉助模版化能夠將其包裹在組件內部。測試

當複用組件 -- 而不是直接拷貝代碼時,給咱們帶來了兩個好處:動畫

  1. 將來的改動變得簡單的多,由於只須要在一處進行
  2. 無需再記住相似代碼被拷貝到的哪幾個甚至上百個地方了

這簡直太基礎了,也是談及複用性時最常被提及的。spa

更高一個層級的就有意思些了:3d

2. 配置

對於某些組件,使用起來是須要變化的。code

一個 Button 組件會有個基本的樣子,或許也要支持帶個圖標。與其爲每一個版本都從新建立一整個新組件,不如使用屬性切換其類型。

添加這些屬性一般不會對組件改動太多,但卻帶來了組件使用的更多靈活性。

注意:這跟使用屬性影響狀態或數據是不一樣的,好比一個 loading prop 或 disabled prop.

3. 適配性

配置的最大問題在於缺少遠見。要預見並支持將來的需求,就得向組件中加入不少屬性。

但若是讓組件變得「可適配」,在不用改變組件的前提下,就能讓其支持咱們甚至不曾設想到的場景。

實現的方法是用一個 slot,從父組件中傳入一塊模版置標。

好比,與直接在 Button 組件上使用一個 text 屬性不一樣的是,咱們可使用 default slot:

<!-- Button.vue -->

<template>
  <button class="btn btn--default" @click="$emit('click')" >
    <slot />
  </button>
</template>
複製代碼

這樣一來,就不受制於傳遞一個 stringnumber 仍是別的什麼了。

若是要增長一個 loading 旋轉動畫,又不想改動 Button 組件,這樣作就行了:

<template>
  <Button>
    <img v-if="loading" src="spinner.svg" />
    摁我
  </Button>
</template>
複製代碼

4. 反轉

與向子組件中傳入一整塊模版置標又有所不一樣的是,咱們還能傳入一組指令,以決定其 如何 渲染。

打個比方,這就像本身烹飪和叫外賣的對比。當你按照菜譜本身動手時,雖然要費些事,但卻盡在掌握 -- 你能夠本身掌控「少量味精」是多少,甚至直接扔掉菜譜本身發揮均可以。

在 Vue 中,使用 scoped slot (做用域插槽) 就能夠達到目的,爲組件增長更多的靈活性了。

(譯註 - 官網上的例子):

<!-- 子組件 CurrentUser -->
<span>
  <slot v-bind:user="user">
    {{ user.lastName }} <!--默認值-->
  </slot>
</span>

<!-- 父組件 -->
<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.age < 10
        ? slotProps.user.lastName
        : `Mr. ${slotProps.user.firstName}` }}
  </template>
</current-user>
複製代碼

5. 擴展

使用 Vue 中的 named slots (具名組件) 能夠在組件中添加一個或多個擴展點。再結合上述的適配反轉,就具有了最大化組件複用性的必要技術。下一步就是在組件中貫徹這些技術,以更簡單地擴展其行爲。

下例中,一個 Modal 組件中分別有 headerdefaultfooter 幾個 slots:

<template>
  <div class="modal">
    <slot name="header">
      <h2>{{ title }}</h2>
    </slot>

    <!-- Default slot for main content -->
    <slot />

    <slot name="footer">
      <Button @click="closeModal">
        Close
      </Button>
    </slot>
  </div>
</template>
複製代碼

例子至關簡單,但咱們已經有了多種擴展這個組件的選項了:

  1. 只是覆寫 default slot 來顯示內容
  2. 顯示默認內容,並增添 header slot 部分
  3. 顯示默認內容,並增添 footer slot 以顯示幾個按鈕
  4. 顯示全部 slots 的內容

6. 嵌套

若是咱們將「擴展點」逐層傳遞,就能達到最終目的。這乍聽起來有點繁瑣,但確實有用,特別是在大型應用的環境中。

從一個完成至關普通功能的基礎組件 A 開始;下一個組件 B 比 A 稍微不那麼普通一些,並在不多的方面擴展 A。以後周而復始,直到你擁有了最終能真正工做的組件。

相似於經典的 OOP 例子,咱們能夠從一個至關通用的 動物 組件擴展到更特別一些的 哺乳動物,接下來是 並最終獲得 貴婦犬

要是咱們的目的就只是 貴婦犬,那這一切確實是費了瞎勁;但在大型應用中,咱們要從一樣但基礎想法上擴展出各類各樣的結果 -- 好比從 中分化出 金毛京巴,或從 哺乳動物 中獲得 貓科動物 並實現 老虎獅子

總結

本文列出了複用 Vue 組件的 6 層手段。這說不上是所有,或許還有其它手段,但已經足夠實用了。

✨ 更多「組件化」的文章 ✨



--End--

查看更多前端好文
請搜索 fewelife 關注公衆號

轉載請註明出處

相關文章
相關標籤/搜索