在使用组件时,常常要像这样组合它们:
<app>
<app-header></app-header>
<app-footer></app-footer>
</app>
注意两点:
- app> 组件不知道它的挂载点会有什么内容,挂载点的内容是由 app> 的父组件决定的。
app> 组件很可能有它自己的模板。当app有自己的模板的时候,app-header和app-footer与app进行组合的时候就不会生效
为了让组件可以组合,我们需要一种方式来混合父组件的内容与子组件自己的模板。这个处理称为内容分发(或 “transclusion”,如果你熟悉 Angular)使用特殊的 slot元素作为原始内容的插槽。相当于在定义模板的时候使用slot起到一个占位的作用,如果在使用模板的时候模板标签内有内容在被填充到slot定义的地方,如果标签内部没有内容,则slot显示
单个slot
<body>
<div id="app">
<my-component></my-component>
<my-component>
<p>This is some original content</p>
<p>This is some more original content</p>
</my-component>
</div>
<template id="MyComponent">
<div>
<h1>This is my component!</h1>
<slot>
如果没有分发内容则显示我。
</slot>
</div>
</template>
<script type="text/javascript">
var vm=new Vue({
el:"#app",
components:{
"my-component":{
template:"#MyComponent"
}
}
})
</script>
</html>
运行结果:
执行过程就是模板内部有其他内容的时候就去填充slot
具名Slot
slot 元素可以用一个特殊特性 name 配置如何分发内容。多个 slot 可以有不同的名字。具名 slot 将匹配内容片段中有对应 slot 特性的元素。
仍然可以有一个匿名 slot,它是默认 slot,作为找不到匹配的内容片段的回退插槽。如果没有默认的 slot,这些找不到匹配的内容片段将被抛弃。
<body>
<div id="app">
<my-component>
<h1 slot="one">One</h1>
<h1 slot="two">Two</h1>
<h1>Default A</h1>
</my-component>
</div>
<template id="MyComponent">
<div>
<slot name="one"></slot>
<slot></slot>
<slot name="two"></slot>
</div>
</template>
</body>
<script type="text/javascript">
var vm=new Vue({
el:"#app",
components:{
"my-component":{
template:"#MyComponent"
}
}
})
</script>
运行结果:
模板标签内的内容会根据slot的指向去寻找组件模板提供的指定的位置