iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0
Modern Web

別再說我不會框架,網頁 Vue 起來!系列 第 12

[Part 4 ] Vue.js 的精隨-元件 Slots

Slots ?

想要傳入內容到子層中,slots 是另一種可以選擇的方式,在 component 預留空間,父層再放入內容。

節錄- Kuro 重新認識 vue.js 中的兩句話:

  • slot 特性是保留一個空間,可以從外部傳入內容,而子元件本身對 slot 沒有控制權
  • 子元件不會知道,也不管 slot 被傳了什麼東西

基本用法

以下範例皆取自 When/Why to Use Vue Scoped Slots

子層:

// ChildComponent.vue
<template>
  <div>
     <slot> Fallback Content </slot>
  </div>
</template>

父層:

// ParentComponent.vue
<template>
   <child-component>
      Override fallback content
   </child-component>
</template>

經過編譯之後,DOM 的內容如下:

<div> Override fallback content </div>

child-component 標籤中的內容Override fallback content 會被置入到 ChildComponent.vue component 中 slot的位置

為什麼需要 ?

再看另一個例子,在 ArticleHeader 元件中,會顯示文章的資訊 (例如: 標題或是描述)

// ArticleHeader.vue
<template>
  <div>
    <slot v-bind:info="info"> {{ info.title }} </slot>
  </div>
</template>

<script>
export default {
  data() {
    return {
      info: {
        title: 'title',
        description: 'description',
      },
    }
  },
}
</script>
// ParentComponent.vue
<template>
  <div>
    <article-header />
  </div>
</template>

如果在外層也需要顯示子層中的 description的話.....

// 錯誤
<template>
  <div>
    <article-header>
        {{ info.description }}
    </article-header>
  </div>
</template>

父層並沒有 info 物件, 會報錯!!!!

這時候,就可以使用 slots....


作用域

scoped slots 讓外層可以取得內層的資料,有兩個步驟:

  1. 透過 v-bindslot 可使用 info
  2. 在父層使用 v-slot 取得 slot 屬性
// ArticleHeader.vue - Binding Slot Props
<template>
  <div>
    <slot v-bind:info="info"> {{ info.title }} </slot>
  </div>
</template>

v-bind:info="info" slot prop 將子元件內的狀態透過 slot 提供給外層

外層透過 templatev-slot 指令

// ParentComponent.vue - using slot props![/images/emoticon/emoticon02.gif](/images/emoticon/emoticon02.gif)
<template>
  <div>
    <child-component>
      <template v-slot="article">
        {{ article.info.description }}
      </template>
    </child-component>
  </div>
</template>

附上官網圖解:
scoped slots

取自 Vue.js- Slots


參考

When/Why to Use Vue Scoped Slots
Summer。桑莫。夏天- Vue.js: Slot

下篇預告

  • 生命週期

每日一句
很高興認識你,收集中...../images/emoticon/emoticon02.gif


上一篇
[番外] 來個 Weather App (續)
下一篇
[Part 5 ] Vue.js 的精隨-元件生命週期 (序)
系列文
別再說我不會框架,網頁 Vue 起來!30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言