# 插槽slot
# 插槽
<div id="root">
<child> <!-- 组件标签 -->
<h1>hello</h1>
</child>
</div>
<script type="text/javascript">
Vue.component('child', { // 子组件
template: '<div><slot></slot></div>' // slot 内容为 'hello'
})
var vm = new Vue({
el: '#root'
})
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
上面代码中,组件标签内的h1
是要插入子组件内部的元素,子组件内使用slot
标签接收父组件插入的h1
标签。
# 默认值
Vue.component('child', {
template: '<div><slot>默认值</slot></div>'
})
2
3
子组件slot
标签内可以添加默认值,它只会在父组件没有传入内容的时候被渲染。
# 具名插槽
提示
自 2.6.0 起,使用v-slot
指令代替slot
attribute 的语法。
<div id="root">
<child>
<template v-slot:header> <!--新语法 只能使用template标签-->
<h1>标题</h1>
</template>
<p>内容</p>
<template v-slot:footer>
<p>页脚</p>
</template>
</child>
</div>
<script type="text/javascript">
Vue.component('child', {
template: `<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>`
})
var vm = new Vue({
el: '#root'
})
</script>
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
27
28
29
30
自2.6.0版本起,具名插槽由原来的slot
标签属性改为v-slot
指令,例v-slot:header
。子组件内仍然是在slot
插槽标签添加name
属性用于分别接收内容。未具名的插槽接收未使用v-slot
指定的内容。
另外,具名插槽同样可以使用默认值。
注意 v-slot
只能添加在 <template
上 (只有一种例外情况 (opens new window)),这一点和已经废弃的 slot
attribute (opens new window)不同。
# 作用域插槽
为了让 user
在父级的插槽内容中可用,我们可以将 user
作为 <slot>
元素的一个 attribute 绑定上去:
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
2
3
4
5
绑定在 <slot>
元素上的 attribute 被称为插槽 prop。现在在父级作用域中,我们可以使用带值的 v-slot
来定义我们提供的插槽 prop 的名字:
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
</current-user>
2
3
4
5
在这个例子中,我们选择将包含所有插槽 prop 的对象命名为 slotProps
,但你也可以使用任意你喜欢的名字。
<div id="root">
<child>
<template v-slot:default="dataObj"> <!--default是默认具名,可省略。但有多个插槽时不能省略。-->
<li>{{dataObj.dataItem}}</li>
</template>
</child>
</div>
<script type="text/javascript">
Vue.component('child', {
data(){
return {
list: [1, 2, 3, 4]
}
},
template: `<div>
<ul>
<slot
v-for="item of list"
:dataItem=item
>
</slot>
</ul>
</div>`
})
var vm = new Vue({
el: '#root'
})
</script>
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
27
28
29
30
# 具名插槽的缩写
跟 v-on
和 v-bind
一样,v-slot
也有缩写,即把参数之前的所有内容 (v-slot:
) 替换为字符 #
。例如 v-slot:header
可以被重写为 #header
:
<base-layout>
<template #header>
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template #footer>
<p>Here's some contact info</p>
</template>
</base-layout>
2
3
4
5
6
7
8
9
10
11
12
然而,和其它指令一样,该缩写只在其有参数的时候才可用。这意味着以下语法是无效的:
<!-- 这样会触发一个警告 -->
<current-user #="{ user }">
{{ user.firstName }}
</current-user>
2
3
4
如果你希望使用缩写的话,你必须始终以明确插槽名取而代之:
<current-user #default="{ user }">
{{ user.firstName }}
</current-user>
2
3