插槽内容
vue实现了一套内容分发的api,这套 API 基于当前的 Web Components 规范草案,将 <slot>
元素作为承载分发内容的出口。
他允许你这样合成组件
<navigation-link url="/profile">
Your Profile
</navigation-link>
然后你在 <navigation-link> 的模板中可能会写为:
<a
v-bind:href="url"
class="nav-link"
>
<slot></slot>
</a>
当组件渲染的时候,这个 <slot> 元素将会被替换为“Your Profile”。插槽内可以包含任何模板代码,包括 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>
如果 <navigation-link> 没有包含一个 <slot> 元素,则任何传入它的内容都会被抛弃。
具名插槽
有时候我们需要多个插槽,<slot>
有一个特殊的特性name
,带有name
属性值的插槽我们叫做具名插槽,它可以用来定义额外的插槽
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
在向具名插槽提供内容的时候,我们可以在一个父组件的 <template> 元素上使用 slot 特性:
<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>
我们还可以保留一个未命名的插槽,这个插槽就是默认的插槽,也就是说所有没有匹配到的内容都会输出到这个默认插槽中,有命名的就会输出到相关的插槽中。
插槽的默认内容
有时候为插槽提供默认的内容是很有用的,例如,一个 <submit-button>
组件可能希望这个按钮的默认内容是“Submit
”,但是同时允许用户覆写为“Save
”、“Upload
”或别的内容。
我们可以在 slot
标签内部指定他的内容。
<button type="submit">
<slot>Submit</slot>
</button>
直接在子组件的 slot
标签中的写入默认值。
如果需要覆盖,再在父组件引用子组件的插槽中修改。
<parent>覆盖slot的默认值</parent>
编译作用域
当你想要在插槽的内部使用数据时:
<navigation-link>
Logged in as {{ user.name }}
</navigation-link>
该插槽可以访问跟这个模板的其它地方相同的实例属性 (也就是说“作用域”是相同的)。但这个插槽不能访问 <navigation-link> 的作用域。例如尝试访问 url 是不会工作的。牢记一条准则:
父组件模板的所有东西都会在父级作用域内编译;子组件模板的所有东西都会在子级作用域内编译。
作用域插槽
有时候你希望提供的组件带有一个可从子组件获取数据可复用的插槽。例如一个简单的 <todo-list> 组件的模板可能包含了如下代码:
<ul>
<li
v-for="todo in todos"
v-bind:key="todo.id"
>
{{ todo.text }}
</li>
</ul>
但是有时候我们需要渲染出个 todo.text
不太一样的东西,有些东西我们不需要或者要进行筛选。
我们可以在li中放入一个 slot
标签,并且将上下文的数据传递进去。
<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>
网友评论