這是我參與8月更文挑戰的第8天,活動詳情查看:8月更文挑戰html
這篇文章咱們來說一下v-slot
的使用方法,以及在使用它的時候咱們須要注意的地方。vue
v-slot
結合<slot>
元素提供具名插槽或須要接收 prop 的插槽。v-slot
的簡寫爲#
,只可用於<template>
和組件
中。編程
假定咱們自定義一個組件my-button爲:markdown
<button>
<slot>提交</slot>
</button>
複製代碼
slot
元素中,咱們能夠給默認值(使用組件不傳內容的時候會顯示默認值,不然默認值會被替換),也能夠爲空,直接爲<slot></slot>
。那麼咱們該怎麼去使用這個組件呢,以下:app
<my-button>
1. 此處什麼都不放,編譯後顯示默認值
2. 此處能夠放字符串
3.此處能夠聽任何模板代碼 或 組件
</my-button>
複製代碼
此外,須要咱們注意的是:父級模板裏的全部內容都是在父級做用域中編譯的;子模板裏的全部內容都是在子做用域中編譯的。也就是說<my-button></my-button>
包裹的內容不能訪問my-button
的做用域。dom
有時咱們須要多個插槽,<slot>
元素有一個特殊的 attribute:name
,咱們可使用這個屬性來寫你須要的插槽,假定一個組件base-layout
以下:ide
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
複製代碼
當屬性name不存在的時候,<slot>
出口會帶有隱含的名字「default」。那麼咱們該怎麼使用呢,以下:函數
<base-layout>
//使用 v-slot
<template v-slot:header>
<h1>name爲header的插槽</h1>
</template>
//默認插槽能夠不用寫 v-slot:default ,可是若是用縮寫的方式就須要寫上 #default
<template #default>
<p>v-slot 時能夠不用寫</p>
<p>縮寫時要加上 #default</p>
</template>
//使用縮寫 #
<template #footer>
<p>縮寫形式</p>
</template>
</base-layout>
複製代碼
爲了讓插槽內容可以訪問子組件中才有的數據,咱們可使用做用於插槽。oop
單個插槽 假定組件todo-list
爲:post
<ul>
<li v-for="(item, index) in items">
<slot :item="item" :index="index"></slot>
</li>
</ul>
複製代碼
使用時咱們能夠有兩種方式:
v-slot
做用在組件上<todo-list v-slot="slotProps">
//slotProps 是個對象,包含了綁定在 slot 上除 name 之外的全部屬性,例如上述包含了item、index
//slotProps 是個變量,能夠取任意名字
//此時不能用template包裹
<span>{{slotProps.item}}</span>
</todo-list>
複製代碼
咱們這個例子是默認插槽,若是例子中是具名插槽,好比 slot
的 name="header"
,那咱們要這樣使用:
<todo-list v-slot:header="slotProps">
<span>{{slotProps.item}}</span>
</todo-list>
複製代碼
v-slot
做用在插槽包裹元素template
上<todo-list>
//必定要用 template 包裹,由於v-slot只能用於 template 或 組件中
<template v-slot="slotProps">
<span>{{slotProps.item}}</span>
</template>
</todo-list>
複製代碼
若是組件給了一個具名插槽,使用方法和1相同。
多個插槽
此時v-slot
只能做用在插槽包裹元素template
上,假定組件todo-list
爲:
<ul>
<li v-for="(item, index) in items">
<slot name="slot1" :item="item" :index="index"></slot>
<slot name="slot2" :item="item" :index="index"></slot>
<slot name="slot3" :item="item" :index="index"></slot>
</li>
</ul>
複製代碼
使用方法以下:
<todo-list>
//slot1
<template v-slot:slot1="slotProps">
<span>{{slotProps.item}}</span>
</template>
//slot2
<template v-slot:slot2="slotProps">
<span>{{slotProps.item}}</span>
</template>
//slot3
<template v-slot:slot3="slotProps">
<span>{{slotProps.item}}</span>
</template>
</todo-list>
複製代碼
經過上述內容咱們知道slotProps是個對象,那麼咱們在使用的時候能夠解構插槽。咱們以1的具名插槽爲例:
<todo-list v-slot:header="{item,index}">
<span>{{item}} {{index}}</span>
</todo-list>
或者
<todo-list v-slot:header="{item:x,index:y}">
<span>{{x}} {{y}}</span>
</todo-list>
複製代碼
動態指令參數也能夠用在 v-slot
上,來定義動態的插槽名,也就是說你能夠根據本身的需求,來動態的改變插槽內容,以下:
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>
複製代碼
假設你有三個插槽,可是你每次只想展現一個插槽內容,那麼咱們就能夠用動態插槽來作這件事。
Vue3統一了普通插槽和做用域插槽。當使用渲染函數時,即 h
,將插槽定義爲當前節點的子對象,以下:
h(LayoutComponent, {}, {
header: () => h('div', this.header),
content: () => h('div', this.content)
})
複製代碼
當你須要以編程方式引用做用域插槽時,Vue3與Vue2的用法是不同的,在Vue3中它們如今被統一到 $slots 選項中,使用以下:
// 2.x 語法
this.$scopedSlots.header
// 3.x 語法
this.$slots.header()
複製代碼
使用動態插槽可讓咱們在處理同一區域複雜內容切換更靈活。
在Vue3
中<template>
裏面能夠放代碼片斷,因此咱們能夠在使用插槽的時候,裏面能夠放不少的dom或組件。
具名插槽和解構插槽Prop均可以讓我更好的去完成需求,咱們能夠根據本身的狀況,去合理的使用它們。