本文涉及的slot有:<slot>,v-slot嗎,vm.$slots,vm.$scopedSlots
廢棄的使用特性:slot,slot-scope,scope(使用v-slot,2.6.0)。
<slot>為vue的內置標簽:用於給組件定義一個插槽,在這個插槽里傳入內容(可以是模板代碼或者組件),達到動態改變組件的目的。
v-slot指令:綁定內容到指定插槽,v-slot 只能添加在一個 <template>
上(當父組件中只提供了默認插槽的內容,v-slot可以寫在組件上,見下面默認插槽縮寫語法)
給插槽設置默認內容,在沒有提供內容的時候被渲染。
<button type="submit"> <slot>Submit</slot> </button>
具名插槽
栗子:<base-layout> 組件
<div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot>//默認插槽,不帶name
的<slot>
出口會帶有隱含的名字“default”。 </main> <footer> <slot name="footer"></slot> </footer> </div>
使用v-slot綁定內容到指定插槽(v-slot縮寫為#,后面必須跟插槽名)
<base-layout>
<template #header>
<h1>Here might be a page title</h1>
</template>
//放入默認插槽中
<p>A paragraph for the main content.</p>
<p>And another one.</p>
//放入默認插槽中
<template #default>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
</template>
<template #footer>
<p>Here's some contact info</p>
</template>
</base-layout>
沒被包裹在有 v-slot
或包裹在v-slot
為default的<template>
中的內容,會被視為默認插槽的內容。
v-slot使用動態插槽名:
<base-layout> <template #[dynamicSlotName]> ... </template> </base-layout>
具有prop的插槽(作用域插槽)
作用:讓插槽內容能夠訪問子組件中的數據
<slot :userNmae="user.name">//userNmae叫做插槽prop </slot>
//父作用域中,v-slot的值為包含默認插槽所有prop一的個對象,對象名取為slotProps <template #default="slotProps"> {{ slotProps.userNmae }} </template>
作用域插槽的使用:基於輸入的 prop 渲染出不同的內容,達到復用插槽的目的。
解構插槽prop
在支持的環境下 (單文件組件或支持解構語法的瀏覽器),可以在v-slot里使用參數解構。
作用域插槽的內部工作原理是將插槽內容包括在一個傳入單個參數的函數里:
function (slotProps) {
// 插槽內容
}
<current-user #default="{ user }"> {{ user.firstName }} </current-user> //參數默認值,用於插槽 prop 是 undefined 的情形 <current-user v-slot="{ user = { firstName: 'Guest' } }"> {{ user.firstName }} </current-user> //user 重命名為 person <current-user v-slot="{ user: person }"> {{ person.firstName }} </current-user>
只提供了默認插槽內容時的v-slot簡寫
當被提供的內容只有默認插槽時,v-slot 直接用在組件上
<current-user v-slot="slotProps"> {{ slotProps.user.firstName }} </current-user>
只要出現多個插槽,請始終為所有的插槽使用完整的基於 <template>
的語法:
<current-user> <template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template> <template v-slot:other="otherSlotProps"> ... </template> </current-user>
vm.$slots
組件vm.$slots.插槽名,返回對應插槽的內容。
栗子:
<anchored-heading :level="1">Hello world!</anchored-heading>
anchored-heading組件的模板為:
Vue.component('anchored-heading', { render: function (createElement) { return createElement( 'h' + this.level, this.$slots.default ) }, props: { level: { type: Number, required: true } } })
anchored-heading 中的 Hello world!
,這些子元素被存儲在組件實例中的 $slots.default
中
vm.$scopedSlots
訪問作用域插槽,得到的是一個返回 VNodes 的函數。
props: ['message'], render: function (createElement) { // `<div><slot :text="message"></slot></div>` return createElement('div', [ this.$scopedSlots.default({ text: this.message }) ]) }
在使用渲染函數,不論當前插槽是否帶有作用域,推薦通過 $scopedSlots
訪問。