1. What is Slots?
Slots is a Vue Components
technique that allows you to place content in a new location or create generic components. What’s the best way to understand how Slots work? I will give the concept to apply it to the situations where you will see the visualization of the project.
Let me start with a simple example:
(first)
1 2 3 4 5 6 7 | <span class="token comment">// Button.vue</span> <span class="token operator"><</span> template <span class="token operator">></span> <span class="token operator"><</span> button <span class="token keyword">class</span> <span class="token operator">=</span> <span class="token string">"btn-wrapper"</span> <span class="token operator">></span> <span class="token operator"><</span> slot <span class="token operator">/</span> <span class="token operator">></span> <span class="token comment">// Vị trí giữa thẻ đóng/mở của Button sẽ được thay thế vào đây.</span> <span class="token operator"><</span> <span class="token operator">/</span> button <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> template <span class="token operator">></span> |
(2)
1 2 3 4 5 6 7 | <span class="token comment">// App.vue</span> <span class="token operator"><</span> template <span class="token operator">></span> <span class="token operator"><</span> div id <span class="token operator">=</span> <span class="token string">"app"</span> <span class="token operator">></span> <span class="token operator"><</span> Button <span class="token operator">></span> Submit <span class="token operator"><</span> <span class="token operator">/</span> Button <span class="token operator">></span> <span class="token comment">// text 'Submit' sẽ được thay vào vị trí của slot tag trong Button component.</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> template <span class="token operator">></span> |
You can also leave a default content when you do not add anything between the opening / closing tags of the Button component
I fix a bit in the code:
(first)
1 2 3 4 5 6 7 | <span class="token comment">// Button.vue</span> <span class="token operator"><</span> template <span class="token operator">></span> <span class="token operator"><</span> button <span class="token keyword">class</span> <span class="token operator">=</span> <span class="token string">"btn-wrapper"</span> <span class="token operator">></span> <span class="token operator"><</span> slot <span class="token operator">></span> Default Content <span class="token operator"><</span> <span class="token operator">/</span> slot <span class="token operator">></span> <span class="token comment">// Vị trí giữa thẻ đóng/mở của Button không có sẽ hiển thị nội dung này.</span> <span class="token operator"><</span> <span class="token operator">/</span> button <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> template <span class="token operator">></span> |
(2)
1 2 3 4 5 6 7 | <span class="token comment">// App.vue</span> <span class="token operator"><</span> template <span class="token operator">></span> <span class="token operator"><</span> div id <span class="token operator">=</span> <span class="token string">"app"</span> <span class="token operator">></span> <span class="token operator"><</span> Button <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> Button <span class="token operator">></span> <span class="token comment">// Nội dung thẻ đóng/mở không có.</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> template <span class="token operator">></span> |
2. Multiple / Named Slots
You can add multiple slots into a component. If you do this, you need to provide a name
for each slot
. If any slot
has no name
, it is the default slot
. For example to create multiple slots
.
1 2 3 4 5 6 7 8 | <span class="token comment">// Card.vue</span> <span class="token operator"><</span> template <span class="token operator">></span> <span class="token operator"><</span> div <span class="token keyword">class</span> <span class="token operator">=</span> <span class="token string">"card-wapper"</span> <span class="token operator">></span> <span class="token operator"><</span> slot name <span class="token operator">=</span> <span class="token string">"title"</span> <span class="token operator">/</span> <span class="token operator">></span> <span class="token comment">// Ở đây sẽ render nội dụng của (1) có v-slot:title trong App .</span> <span class="token operator"><</span> slot <span class="token operator">/</span> <span class="token operator">></span> <span class="token comment">// Ở đây sẽ render nội dung của (2).</span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> template <span class="token operator">></span> |
1 2 3 4 5 6 7 8 9 10 11 12 | <span class="token comment">// App.vue</span> <span class="token operator"><</span> template <span class="token operator">></span> <span class="token operator"><</span> div id <span class="token operator">=</span> <span class="token string">"app"</span> <span class="token operator">></span> <span class="token operator"><</span> Card <span class="token operator">></span> <span class="token operator"><</span> template v <span class="token operator">-</span> slot <span class="token operator">:</span> title <span class="token operator">></span> <span class="token comment">// sử dụng v-slot directive để biết được là phần code trong `template` sẽ được thêm vào slot có name="title" trong Card component (1).</span> <span class="token operator"><</span> h1 <span class="token operator">></span> Title <span class="token operator"><</span> <span class="token operator">/</span> h1 <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> template <span class="token operator">></span> <span class="token operator"><</span> div <span class="token operator">></span> Content <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token comment">// render trong default slot (2).</span> <span class="token operator"><</span> <span class="token operator">/</span> Card <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> template <span class="token operator">></span> |
3. Scoped Slot
One thing you need to know is that you can pass the data / function from the children component
to the parent component
. To demonstrate this, we will create a CurrentUser
component:
1 2 3 4 5 6 7 8 9 | <span class="token comment">// CurrentUser.vue</span> <span class="token operator"><</span> template <span class="token operator">></span> <span class="token operator"><</span> span <span class="token operator">></span> <span class="token operator"><</span> slot v <span class="token operator">-</span> bind <span class="token operator">:</span> user <span class="token operator">=</span> <span class="token string">"user"</span> <span class="token operator">></span> <span class="token comment">// bind data vào slot.</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> user <span class="token punctuation">.</span> firstName <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token operator"><</span> <span class="token operator">/</span> slot <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> span <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> template <span class="token operator">></span> |
1 2 3 4 5 6 7 8 9 | <span class="token comment">// App.vue</span> <span class="token operator"><</span> template <span class="token operator">></span> <span class="token operator"><</span> div id <span class="token operator">=</span> <span class="token string">"app"</span> <span class="token operator">></span> <span class="token operator"><</span> CurrentUser v <span class="token operator">-</span> slot <span class="token operator">:</span> <span class="token keyword">default</span> <span class="token operator">=</span> <span class="token string">"slotProps"</span> <span class="token operator">></span> <span class="token comment">// Lấy data từ slot.</span> <span class="token punctuation">{</span> <span class="token punctuation">{</span> slotProps <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token comment">// Xem slotProps có gì nhé.</span> <span class="token operator"><</span> <span class="token operator">/</span> CurrentUser <span class="token operator">></span> <span class="token operator"><</span> <span class="token operator">/</span> div <span class="token operator">></span> <span class="token operator"><</span> template <span class="token operator">></span> |
Some note:
slotProps
you can replace with a name you want.- If you are only using the
default slot
, you can remove thetemplate
tag and put thev-slot
directive directly in theCurrentUser
tag. - You can use
Object Destructuring
to make a reference directly to the data instead of using a variable name:v-slot="slotProps"
=>v-slot="{ user }"
. - If the
default slot
you can write as:v-slot:default="slotProps"
=>v-slot="slotProps"
. v-slot
can be abbreviated to#
.- default slot:
v-slot="slotProps"
=>#default="shotProps"
. - named slot:
v-slot:title="slotProps"
=>#title="shotProps"
.
- default slot:
If you find this article useful to you when you first learn Vue, give me 1 vote [email protected] # $% ^ & *