Vue 作用域插槽 (Scoped Slots) 詳解:打破作用域限制的元件橋樑
在 Vue 的元件體系中,預設遵循著嚴格的單向資料流與作用域限制:父元件無法直接存取子元件內部的資料。
然而,當您開發高度封裝的元件(如:資料表格 DataTable、自動完成列表 Autocomplete)時,「由子元件提供資料,但由父元件決定渲染樣式」 的需求便會出現。這正是 作用域插槽 (Scoped Slots) 大顯身手的時刻。
為什麼需要作用域插槽?
一句話總結:子元件掌握 資料(Data),但不知道如何渲染;父元件掌握 渲染邏輯(UI),但拿不到資料。 作用域插槽就像一座橋樑,讓子元件能像「傳遞 Props」一樣,把內部數據回傳給父元件的插槽內容。
實作步驟:從資料綁定到接收
子元件:定義插槽並「綁定」數據
在子元件中,我們透過 :propName="value" 的方式,將資料掛載到 <slot> 標籤上。
vue
<!-- /components/UserList.vue -->
<script setup>
import { reactive } from "vue";
const users = reactive([
{ id: 9, name: "Away", role: "admin" },
{ id: 10, name: "Tony", role: "user" },
{ id: 11, name: "Mary", role: "user" },
]);
</script>
<template>
<ul>
<li v-for="u in users" :key="u.id">
<slot :user="u"></slot>
</li>
</ul>
</template>父元件:接收數據並「自定義」外觀
父元件透過 v-slot 指令接收一個物件(通常命名為 slotProps),該物件包含了子元件回傳的所有數據。
vue
<!-- /views/Slot.vue -->
<script setup>
import UserList from "@/components/UserList.vue";
function clickHandler(id) {
console.log(id);
}
</script>
<template>
<UserList v-slot="slotProps">
{{ slotProps.user.name }} ({{ slotProps.user.role }})
<input
type="button"
value="edit"
@click="clickHandler(slotProps.user.id)"
/>
</UserList>
</template>TIP
簡單來說,子元件裡有資料,但不知道怎麼渲染;父元件知道怎麼渲染,但沒有資料。作用域插槽就是那座橋樑,讓子元件把資料傳給父元件的插槽內容。
進階技巧:解構插槽 Prop (Destructuring)
為了讓程式碼更簡潔,您可以使用 ES6 解構語法直接取得資料,這是現代 Vue 開發中最推薦的寫法:
vue
<UserList v-slot="{ user }">
{{ user.name }}
</UserList>