Vue.js slots: 爲何你須要它們?

也許你已經看過了Vue.js slots的文檔。我對這個功能從「爲何你可能須要它」到「沒有它我怎麼可能工做」的態度轉變很是快。
雖然文檔已經解釋了它的概念,可是這裏有一個關於slots怎麼改進應用程序代碼庫的真實例子。
在我看來,slots是vue最有用和最有趣的特性之一。雖然這是web組件所推薦的標準,可是我不知道有其餘框架已經實現了這一特性。解釋slots的做用很簡單,可是很難解釋它爲何有用(若是不使用「可組合性」這個術語),因此我要給你一個使用例子。css

假設你的app有不少表單,表單包含幾個部分:html

  • 表單頭部:包含關於表單的信息
  • 表單元素:供用戶輸入
  • 按鈕

如今你想要把表單抽象爲一個獨立組件。你那些使用react和angular的同事告訴你,你須要使用相似React的組合vs繼承或者Angular1的Transclude這樣的特性,因而你找到了slots的文檔。vue

你建立了這樣一個組件:react

<!-- FormHelper.vue -->
<form class="form">
  <h3>{{ title }}</h3>
  <slot></slot><!-- children will go here -->
  <button>Submit</button>
</form>

使用方法以下:angularjs

<!-- App.vue -->
<form-helper title="Password Reset">
  <input type="text" name="name" value="">
  <input type="text" name="email" value="">
</form-helper>

這樣就能夠正常運行了。但是,產品告訴你,一個特定的表單須要一個文本塊來得到幫助信息的標題,按鈕名要改成「Request」。這超出了「children」能作的範圍。web

<!-- FormHelper.vue -->
<form class="form">
  <h3>{{ title }}</h3>
  <div :v-if="hasHelp">{{ helpMessage }}</div>
  <slot></slot><!-- children will go here -->
  <button>{{ customButtonName }}</button>
</form>

上述代碼可能會出現一些問題,若是須要更多按鈕、更多交互等等這些狀況,怎麼辦?幸虧,vuejs提供了一個更簡潔的解決方案:具名slots。因而,你把代碼改爲下面這樣:bootstrap

<!-- FormHelper.vue -->
<form class="form">
  <h3>{{ title }}</h3>
  <slot name="help"></slot>
  <slot name="elements"></slot><!-- children will go here -->
  <slot name="buttons"></slot>
</form>

使用方法:api

<!-- App.vue -->
<form-helper title="Request Form">
  <div slot="help">
    Please ask your manager before requesting hardware.
  </div>
  <div slot="elements">
    <input type="text" name="item_name" value="">
    <input type="text" name="item_value" value="">
  </div>
  <div slot="buttons">
    <button type="button" name="button">Request</button>
  </div>
</form-helper>

在我看來,關鍵思想是:app

將slots看成傳遞給子組件的屬性。就像傳遞字符串、整數和對象,而slots是傳遞一個子dom樹,讓子組件能夠在任何須要的地方使用。框架

使用slots的其餘場景:

使用slots的更多優勢:

  • 子組件用於樣式和展現,業務邏輯都保留在父元素中。
  • 若是沒有傳遞內容給slots,就不會展現東西。這讓你能夠很好地複用它們,而且只在你想要的slots中傳遞。
相關文章
相關標籤/搜索