组件可以在 template 当中设置一个 slot 的 tag,用于在使用该组件时,传入一些内容来替换掉 slot
1
2
3
4
5
6
7
8
9
10
< FancyButton >
Click me ! <!-- slot content -->
</ FancyButton >
< button class = "fancy-btn" >
< slot ></ slot > <!-- slot outlet -->
</ button >
// final output
< button class = "fancy-btn" > Click me ! </ button >
传给 slot 的内容可以是文本,也可以是 html element
scopeslot 的渲染 scope 限于父组件,当传入一个变量,这个变量只能访问父组件,而不能访问子组件的变量
Expressions in the parent template only have access to the parent scope; expressions in the child template only have access to the child scope.
有些情况下 slot 的内容需要根据组件本身的变量来设置。这种情况可以像传递 props 给组件一样传递 attributes 给组件。这种时候 slot 的内容就可以根据子组件的变量来获取。
1
2
3
4
5
6
7
8
<!-- < MyComponent > template -->
< div >
< slot :text ="greetingMessage" :count ="1" ></ slot >
</ div >
< MyComponent v-slot ="slotProps" >
{{ slotProps.text }} {{ slotProps.count }}
</ MyComponent >
本质上可以当作是传递了一个函数下去,由组件调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
MyComponent ({
// passing the default slot, but as a function
default : ( slotProps ) => {
return ` ${ slotProps . text } ${ slotProps . count } `
}
})
function MyComponent ( slots ) {
const greetingMessage = 'hello'
return `<div> ${
// call the slot function with props!
slots . default ({ text : greetingMessage , count : 1 } )
}</div>`
}
fallback content组件可以为 slot 设置默认值
1
2
3
4
5
< button type = "submit" >
< slot >
Submit <!-- fallback content -->
</ slot >
</ button >
named slot如果一个组件中有多个 slot,可以通过 name 属性来进行区分。使用时可以通过属性 v-slot:slotName
或者缩写 #slotName
明确是传给哪一个 slot,不填时默认是 default
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
< div class = "container" >
< header >
< slot name = "header" ></ slot >
</ header >
< main >
< slot ></ slot >
</ main >
< footer >
< slot name = "footer" ></ slot >
</ footer >
</ div >
< BaseLayout >
< template v -slot : header >
< h1 > Here might be a page title </ h1 >
</ template >
< template # default >
< p > A paragraph for the main content .</ p >
< p > And another one .</ p >
</ template >
< template # footer >
< p > Here ' s some contact info </ p >
</ template >
</ BaseLayout >
默认顶级的元素都会传递给 default slot
1
2
3
4
5
6
7
8
9
10
11
12
13
< BaseLayout >
< template # header >
< h1 > Here might be a page title </ h1 >
</ template >
<!-- implicit default slot -->
< p > A paragraph for the main content .</ p >
< p > And another one .</ p >
< template # footer >
< p > Here ' s some contact info </ p >
</ template >
</ BaseLayout >
动态 slot name通过中括号可以使用动态变量或表达式作为 slot name
1
2
3
4
5
6
7
8
9
10
< base-layout >
< template v -slot : [ dynamicSlotName ] >
...
</ template >
<!-- with shorthand -->
< template #[ dynamicSlotName ] >
...
</ template >
< /base-layout>