一个简单的插槽示例:
<navigation-link url="/profile">
Your Profile
</navigation-link>
在navigation-link模板中写
<a v-bind:href="url" class="nav-link">
<slot></slot>
</a>
插槽内可以包含任何模板代码,包括 HTML:
<navigation-link url="/profile">
<!-- 添加一个 Font Awesome 图标 -->
<span class="fa fa-user"></span>
Your Profile
</navigation-link>
甚至其它的组件:
<navigation-link url="/profile">
<!-- 添加一个图标的组件 -->
<font-awesome-icon name="user"></font-awesome-icon>
Your Profile
</navigation-link>
具名插槽,方便多个插入值:
模板中:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
使用:
<base-layout>
<template slot="header">
<h1>Here might be a page title</h1>
</template>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<template slot="footer">
<p>Here's some contact info</p>
</template>
</base-layout>
另一种 slot 特性的用法是直接用在一个普通的元素上:
<base-layout>
<h1 slot="header">Here might be a page title</h1>
<p>A paragraph for the main content.</p>
<p>And another one.</p>
<p slot="footer">Here's some contact info</p>
</base-layout>
插槽的默认内容:
在模板中slot便签直接写入默认内容:
<button type="submit">
<slot>Submit</slot>
</button>
编译作用域:
当你想在插槽内使用数据时,例如:
<navigation-link url="/profile">
Logged in as {{ user.name }}
</navigation-link>
该插槽可以访问跟这个模板的其它地方相同的实例属性 (也就是说“作用域”是相同的)。但这个插槽不能访问 <navigation-link> 的作用域。例如尝试访问 url 是不会工作的。牢记一条准则:
父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。
作用域插槽:
例如一个简单的 组件的模板可能包含了如下代码:
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id"
>
{{ todo.text }}
</li>
</ul>
在以上代码中,如果想为不同的组件定义不同的text显示格式,那么也可以通过插槽来实现。
<div id='ul-template'>
<ul-test v-bind:todos='todos'>
<template slot-scope="slotProps">
<!-- 为待办项自定义一个模板,-->
<!-- 通过 `slotProps` 定制每个待办项。-->
<span v-if="slotProps.todo.isComplete">√</span>
{{ slotProps.todo.text }}
</template>
</ul-test>
</div>
Vue.component('ul-test',{
props:['todos'],
template:`
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id"
>
<!-- 我们为每个 todo 准备了一个插槽,-->
<!-- 将 todo 对象作为一个插槽的 prop 传入。-->
<slot v-bind:todo="todo">
<!-- 回退的内容 -->
{{ todo.text }}
</slot>
</li>
</ul>
`
})
new Vue({
el:"#ul-template",
data:{
todos:[
{id:1,text:'text1',isComplete:true},
{id:2,text:'text2',isComplete:false}
]
}
})
在 2.5.0+,slot-scope 不再限制在 元素上使用,而可以用在插槽内的任何元素或组件上。
解构 slot-scope:
如果一个 JavaScript 表达式在一个函数定义的参数位置有效,那么这个表达式实际上就可以被 slot-scope 接受。也就是说你可以在支持的环境下 (单文件组件或现代浏览器),在这些表达式中使用 ES2015 解构语法。例如:
<todo-list v-bind:todos="todos">
<template slot-scope="{ todo }">
<span v-if="todo.isComplete">✓</span>
{{ todo.text }}
</template>
</todo-list>
这会使作用域插槽变得更干净一些。
可以从this.$slots
获取 VNodes 列表中的静态内容
还可以从 this.$scopedSlots
中获得能用作函数的作用域插槽