Vuejs
<slot>
內容在父模板編譯,基於 Vue 的定義,在父模板中編譯的內容訪問 parent scope
,在子模板中編譯的內容訪問 child scope
,我們不能使用插槽內容訪問 child scope
的 property
。
例如來說,我有一個子組件內容如下:
Vue.component('my-component', {
data() {
return {
user: {
name: 'Tony',
nickname: 'TT',
age: 23,
born: 1999
},
}
},
template: `<div>
<h2>name:<slot name="name">{{ user.nickname }}</slot></h2>
<p>age:<slot name="age">{{ user.age }}</slot></p>
</div>`,
})
假如今天父組件想將 user.nickname
更改為呈現子組件中的 user.name
,如下方程式碼:
const vm = new Vue({
el: '#app',
data: {},
template: `
<div id="app">
<my-component>
<template v-slot:name>{{ user.name }}</template>
<template v-slot:age>{{ user.born }}</template>
</my-copmonent>
</div>`,
})
不出意外的,由於該處不能訪問 child scope
,Vue 將會給你滿江紅,和你說 user
是未定義的。
這是由於 user
位於子組件中,下方 Vue devtools 顯示了 root
和 my-component
instance 各自的數據,在各自的模板中可以訪問各自實體的數據。
若是想要在插槽中使用 child scope
中的數據,Vue 提供了一種方式,作用域插槽,透過該方式便可以使插槽使用子組件數據。
如果想要使用插槽訪問 child scope
的內容,可以使用 slot Prop
,將想要給插槽訪問的 child scope
數據透過 v-bind
綁定在 <slot>
中,此時父組件的 插槽
便可以訪問該數據:
要使用作用域插槽,透過以下步驟:
v-bind
綁定插槽 propv-slot:插槽名稱="插槽 prop 名稱"
定義插槽 prop 名稱。(沒有給予插槽名稱時為 default
,但使用多個插槽建議一律使用有參數的 v-slot
)Vue.component('my-component', {
data() {
return {
user: {
name: 'Tony',
nickname: 'TT',
age: 23,
born: 1999
},
}
},
template: `<div>
<h2>name:<slot name="name" v-bind:user="user">{{ user.nickname }}</slot></h2>
<p>age:<slot name="age" v-bind:user="user">{{ user.age }}</slot></p>
</div>`,
})
const vm = new Vue({
el: '#app',
template: `
<div id="app">
<my-component>
<template v-slot:name="slotProp">{{ slotProp.user.name }}</template>
<template v-slot:age="otherSlotProp">{{ otherSlotProp.user.born }}</template>
</my-component>
</div>`,
})
上方的插槽 prop 由於本身在 Vue 中的作用原理如下:
function (slotProp) { ... }
所以我們可以使用解構的方式簡化程式碼:
<my-component>
<template v-slot:name="{ user }">{{ user.name }}</template>
<template v-slot:age="{ user }">{{ user.born }}</template>
</my-component>
運用解構語法更可以支持我們重命名:
<my-component>
<template v-slot:name="{ user: person }">{{ person.name }}</template>
<template v-slot:age="{ user: person }">{{ person.born }}</template>
</my-component>
或是定義默認內容,適用於沒有 slotProp 的情況:
<my-component>
<template v-slot:name="{ user: { name: 'Ady'} }">{{ user.name }}</template>
<template v-slot:age="{ user: { born: 1992 } }">{{ user.born }}</template>
</my-component>
v-slot
也支持動態參數名稱:
<my-component>
<template v-slot:[name]="{ user: { name: 'Ady'} }">{{ user.name }}</template>
<template v-slot:[age]="{ user: { born: 1992 } }">{{ user.born }}</template>
</my-component>
插槽也有縮寫語法,只適用於 具名
插槽,寫法很簡單,只需要將 v-slot
取代成 #
<my-component>
<template v-slot:name="{ user: { name: 'Ady'} }">{{ user.name }}</template>
<template v-slot:age="{ user: { born: 1992 } }">{{ user.born }}</template>
</my-component>
可以簡化為:
<my-component>
<template #name="{ user: { name: 'Ady'} }">{{ user.name }}</template>
<template #age="{ user: { born: 1992 } }">{{ user.born }}</template>
</my-component>
以上為此次內容,感謝看到這裡的你,我們明天見。
若是文中有任何錯誤、錯字、想討論的內容,歡迎各位大大不吝鞭笞指正、交流分享,筆者不慎感激 ✦ ✦ ✦
▶︎ 筆者 github:https://github.com/YUN-RU-TSENG
▶︎ 老王賣瓜之筆者另一篇鐵人:每天來點 CSS Specification
▶︎ 倘若不斷向深處扎根,似乎就能茁壯成長 - RM