vue插槽slot

1.匿名插槽

它容許你像這樣合成組件:url

<navigation-link url="/profile">
  Your Profile
</navigation-link>

 而後你在 <navigation-link> 的模板中可能會寫爲:spa

<a
  v-bind:href="url"
  class="nav-link"
>
  <slot></slot>
</a>

當組件渲染的時候,這個 <slot> 元素將會被替換爲「Your Profile」。插槽內能夠包含任何模板代碼,包括 HTML:code

<navigation-link url="/profile">
  <!-- 添加一個 Font Awesome 圖標 -->
  <span class="fa fa-user"></span>
  Your Profile
</navigation-link>

甚至其它的組件:對象

<navigation-link url="/profile">
  <!-- 添加一個圖標的組件 -->
  <font-awesome-icon name="user"></font-awesome-icon>
  Your Profile
</navigation-link>

若是 <navigation-link> 沒有包含一個 <slot> 元素,則任何傳入它的內容都會被拋棄。作用域

2.具名插槽

有些時候咱們須要多個插槽。例如,一個假設的 <base-layout> 組件的模板以下:it

<div class="container">
  <header>
    <!-- 咱們但願把頁頭放這裏 -->
  </header>
  <main>
    <!-- 咱們但願把主要內容放這裏 -->
  </main>
  <footer>
    <!-- 咱們但願把頁腳放這裏 -->
  </footer>
</div>

對於這樣的狀況,<slot> 元素有一個特殊的特性:name。這個特性能夠用來定義額外的插槽:io

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

在向具名插槽提供內容的時候,咱們能夠在一個父組件的 <template> 元素上使用 slot 特性:table

<base-layout>
  <template slot="header">
    <h1>Here might be a page title</h1>
  </template>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <template slot="footer">
    <p>Here's some contact info</p>
  </template>
</base-layout>

另外一種 slot 特性的用法是直接用在一個普通的元素上:模板

<base-layout>
  <h1 slot="header">Here might be a page title</h1>

  <p>A paragraph for the main content.</p>
  <p>And another one.</p>

  <p slot="footer">Here's some contact info</p>
</base-layout>

咱們仍是能夠保留一個未命名插槽,這個插槽是默認插槽,也就是說它會做爲全部未匹配到插槽的內容的統一出口。上述兩個示例渲染出來的 HTML 都將會是:class

<div class="container">
  <header>
    <h1>Here might be a page title</h1>
  </header>
  <main>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </main>
  <footer>
    <p>Here's some contact info</p>
  </footer>
</div>

3.插槽的默認內容

有的時候爲插槽提供默認的內容是頗有用的。例如,一個 <submit-button> 組件可能但願這個按鈕的默認內容是「Submit」,可是同時容許用戶覆寫爲「Save」、「Upload」或別的內容。

你能夠在組件模板裏的 <slot> 標籤內部指定默認的內容來作到這一點。

<button type="submit">
  <slot>Submit</slot>
</button>

若是父組件爲這個插槽提供了內容,則默認的內容會被替換掉。

4.做用域插槽

有的時候你但願提供的組件帶有一個可從子組件獲取數據的可複用的插槽。例如一個簡單的 <todo-list> 組件的模板可能包含了以下代碼:

<ul>
  <li
    v-for="todo in todos"
    v-bind:key="todo.id">
    {{ todo.text }}
  </li>
</ul>

可是在咱們應用的某些部分,咱們但願每一個獨立的待辦項渲染出和 todo.text 不太同樣的東西。這也是做用域插槽的用武之地。

爲了讓這個特性成爲可能,你須要作的所有事情就是將待辦項內容包裹在一個 <slot> 元素上,而後將全部和其上下文相關的數據傳遞給這個插槽:在這個例子中,這個數據是 todo 對象:

<ul>
  <li
    v-for="todo in todos"
    v-bind:key="todo.id"
  >
    <!-- 咱們爲每一個 todo 準備了一個插槽,-->
    <!-- 將 `todo` 對象做爲一個插槽的 prop 傳入。-->
    <slot v-bind:todo="todo">
      <!-- 回退的內容 -->
      {{ todo.text }}
    </slot>
  </li>
</ul>

如今當咱們使用 <todo-list> 組件的時候,咱們能夠選擇爲待辦項定義一個不同的 <template> 做爲替代方案,而且能夠經過 slot-scope 特性從子組件獲取數據:

<todo-list v-bind:todos="todos">
  <!-- 將 `slotProps` 定義爲插槽做用域的名字 -->
  <template slot-scope="slotProps">
    <!-- 爲待辦項自定義一個模板,-->
    <!-- 經過 `slotProps` 定製每一個待辦項。-->
    <span v-if="slotProps.todo.isComplete">✓</span>
    {{ slotProps.todo.text }}
  </template>
</todo-list>

在 2.5.0 以前,slot-scope 被命名爲 scope 且被限制只能在 <template> 元素上使用。從 2.5.0 開始,slot-scope 再也不具備這些限制,而能夠用在插槽內的任何元素或組件上。

相關文章
相關標籤/搜索