iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 26
0
自我挑戰組

每天來點 Vue.js 吧系列 第 26

Vue slot:編譯作用域、後備內容

  • 分享至 

  • xImage
  •  
tags: Vuejs

<slot> 是什麼? ✐

Vue 中的 <slot> 是 Vue 內置的組件 build-in component 的其中一種組件,靈感來源於 web component,是一個 content distribution API。透過 <slot> 提供的保留空間,我們可以顯示從一個組件傳遞到另一個組件的內容,該內容可以是數據、HTML 元素(或任何模板代碼內容),而 <slot> 元素作為承載內容分發的出口,則會被該分發內容 替換取代

<slot>props 可以做到在子組件中呈現內容,明顯的差距之一是 <slot> 可以插入 HTML element 而不必擔心 XSS 問題。

<slot> 簡單的使用方式如下:

假如今天我們想要做一個組件,其文字內容是透過 <slot> 分發:

Vue.component('my-comonent', {
  template: `<button><slot></slot></button>`
})
const vm = new Vue({
  el: '#app',
  data: {
    text: 'BUTTON'
  },
  template: `<div id="app"><my-comonent>{{ text }}</my-comonent></div>`,
})

my-comonentslot 將被分發的 {{ text }} 取代,按鈕會呈現如下內容。

簡單來說:

slot 內置組件將被設置在要有插槽的 子組件 上,而使用有插槽組件的 父組件,便可以寫入要取代 <slot> 的內容。

注意:若是沒有在子組件中使用 <slot>,父組件傳入子組件的內容將會被拋棄,如下方內容:

Vue.component('my-comonent', {
  template: `<button></button>`
})

const vm = new Vue({
  el: '#app',
  data: {
    text: 'BUTTON'
  },
  template: `<div id="app"><my-comonent>{{ text }}</my-comonent></div>`,
})

這次 my-comonent 中沒有寫入要作為內容分發的 <slot>,按鈕不會呈現文字內容,該文字 被拋棄

編譯 scope

插槽中使用的數據內容 scope 為所處模板的 scope,也就是當下模板 instance 的 property。

Vue.component('my-comonent', {
  props: ['url'],
  template: `<button><slot></slot></button>`
})
const vm = new Vue({
  el: '#app',
  data: {
    text: 'BUTTON',
  },
  template: `<div id="app"><my-comonent url="xxx">{{ text }}</my-comonent></div>`,
})

以上述範例來說,插槽可以訪問 vm instance scope,不能訪問 my-comonent scope 內容 url

總結來說:

  • 父級模板 的內容都是在 父級 scope 編譯的,所以上述範例中插槽可以訪問 父級 scope
  • 子級模板 的內容都是在 子級 scope 編譯的,內容可以訪問 子級作用域 scope

後備內容

可以為插槽準備 後備內容,當想要設置一個 預設默認值 時,該功能很有用。

Vue.component('my-comonent', {
  template: `<button><slot>Default</slot></button>`
})

const vm = new Vue({
  el: '#app',
  data: {
    text: 'BUTTON'
  },
  template: `<div id="app"><my-comonent></my-comonent></div>`,
})

按鈕由於提供了後備內容,插槽沒傳入內容會呈現如下的默認值:

以上為此次內容,感謝看到這裡的你,我們明天見。


若是文中有任何錯誤、錯字、想討論的內容,歡迎各位大大不吝鞭笞指正、交流分享,筆者不慎感激 ✦ ✦ ✦

▶︎ 筆者 github:https://github.com/YUN-RU-TSENG
▶︎ 老王賣瓜之筆者另一篇鐵人:每天來點 CSS Specification

▶︎ 倘若不斷向深處扎根,似乎就能茁壯成長 - RM


參考資料:

  1. Vuejs.org 2.x
  2. Vue Slots | Understanding of Slots in Vuejs | Learn Vuejs Slots

上一篇
Vue 透過 `$listeners` 在子組件特定元素上監聽原生事件
下一篇
Vue slot: 具名插槽
系列文
每天來點 Vue.js 吧30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
Chris
iT邦新手 3 級 ‧ 2020-10-12 11:16:50

/images/emoticon/emoticon31.gif

抖抖抖抖抖

我要留言

立即登入留言