Vue-我想放的是內容不是資料(Slot)

寫元件時會用到。

這個就跟 React 的「Children」是差不多的東西,讓我們可以直接把 template 傳給元件使用,只是在 Vue 裡面叫作「Slot」,而且功能也更多一些。

App.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<template>
<div class="container">
<div class="block">
<button class="btn" @click="onOpen">Show modal</button>
</div>
</div>
<Modal v-show="isModal" :isSale="isSale" @onClose="onClose">
<!-- basic slot -->
<h1>PeaNu</h1>
<p>peanu@peanu.dev</p>
<!-- naming slot -->
<template v-slot:actions>
<button class="btn">Add Friend</button>
<button class="btn">Block User</button>
</template>
</Modal>
</template>

上面是把內容寫入 Modal 的 slot 中,Vue 比較特別的地方是還可以幫 slot 命名,使用方式是透過 <template>v-slot:名稱 來定義,接著在元件中就可以透過名稱來做區隔。

Modal.vue:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<div class="backdrop" @click.self="onClick">
<div class="modal" :class="{ sale: isSale }">
<div class="content">
<!-- basic slot -->
<slot>default content</slot>
<div class="action">
<!-- naming slot -->
<slot name="actions">deafault content</slot>
</div>
</div>
</div>
</div>
</template>

附註:default content 的意思是預設內容,會在沒有傳入 slot 時顯示

在元件中要接收 slot 會直接透過 <slot> 來接,如果是命名 slot 的話就再加上 name 屬性來區隔開來就行了。

想知道更多細節的話可以到 這裡 看範例會比較快。

順道一提「命名 slot」有提供語法糖,可以用 #name 的方式來表示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<template>
<div class="container">
<div class="block">
<button class="btn" @click="onOpen">Show modal</button>
</div>
</div>
<Modal v-show="isModal" :isSale="isSale" @onClose="onClose">
<h1>PeaNu</h1>
<p>peanu@peanu.dev</p>
<!-- 用 # 來表示 -->
<template #actions>
<button class="btn">Add Friend</button>
<button class="btn">Block User</button>
</template>
</Modal>
</template>
Vue-窩想放到其他位置可以嗎?(Teleport) Vue-接住我的事件吧($emit)
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×