关于slot是这样说的, 除非子组件模板包含至少一个 slot 插口,否则父组件的内容将会被丢弃。当子组件模板只有一个没有属性的 slot 时,父组件整个内容片段将插入到 slot 所在的 DOM 位置,并替换掉 slot 标签本身。
最初在 slot 标签中的任何内容都被视为备用内容。备用内容在子组件的作用域内编译,并且只有在宿主元素为空,且没有要插入的内容时才显示备用内容。
在子组件内使用特殊的slot元素就可以为这个子组件添加一个 slot (插槽),在父组件模板里,插入在子组件标签内的所有内容将替代子组件的slot标签及它的内容.示例代码如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>示例</title>
</head>
<body>
<div id="app">
<child-component>
<p>分发的内容</p>
<p>更多分发的内容</p>
</child-component>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
Vue.component('child-component', {
template: '\
<div>\
<slot>\
<p>如果父组件没用插入内容,我将作为默认出现</p>\
</slot>\
</div>'
});
var app = new Vue({
el: '#app'
})
</script>
</body>
</html>
子组件 child-component 的模板内定义一个 slot 元素,并且用一个
作为默认的内容,在父组件没有使用 slot 时, 会渲染这段默认的文本;如果写入了 slot ,那就会替换整个 slot.所以上列渲染后的结果为:
<div id="app">
<div>
<p>分发的内容</p>
<p>更多分发的内容</p>
</div>
</div>
注意:子组件slot内的备用内容,它的作用域时子组件本身.
给 slot 元素指定一个 name 后可以分发多个内容,具名 Slot 可以与单个 Slot 共存,例如下面的示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>示例</title>
</head>
<body>
<div id="app">
<child-component>
<h2 slot="header">标题</h2>
<p>正文内容</p>
<p>更多正文内容</p>
<div slot="footer">底部信息</div>
</child-component>
</div>
<script src="https://unpkg.com/vue/dist/vue.min.js"></script>
<script>
Vue.component('child-component', {
template: '\
<div class="component">\
<div class="header">\
<slot name="header"></slot>\
</div>\
<div class="main">\
<slot></slot>\
</div>\
<div class="footer">\
<slot name="footer"></slot>\
</div>\
</div>'
});
var app = new Vue({
el: '#app'
})
</script>
</body>
</html>
子组件内声明了3个 slot 元素,其中在
内的slot 没用使用 name 特性,它将作为默认 slot 出现,父组件没有使用 slot 特性的元素与内容都将出现在这里. 如果没有指定默认的匿名 slot, 父组件内多余的内容片段都将被抛弃. 上例最终渲染后的结果为:
div id="app">
<div class="container">
<div class="header">
<h2>标题</h2>
</div>
<div class="main">
<p>正文内容</p>
<p>更多的正文内容</p>
</div>
<div class="footer">
<div>底部信息</div>
</div>
</div>
</div>
在组合使用组件时,内容分发API至关重要.
说白了就是我在组件上的属性,可以在组件元素内使用!
先看一个最简单的例子!!
我们给slot元素上定义一个属性say(随便定义的!),接下来在使用组件child,然后在template元素上添加属性slot-scope!!随便起个名字a
我们把a打印一下发现是 {"say" : "你好"},也就是slot上面的属性和值组成的键值对!!!
这就是作用域插槽!
<div id="app">
<child>
<template slot-scope="a">
<!-- {"say":"你好"} -->
{{a}}
</template>
</child>
</div>
<script>
Vue.component('child',{
template:`
<div>
<slot say="你好"></slot>
</div>
`
})
let vm = new Vue({
el:'#app',
data:{
}
})
</script>
再看一下下面的例子:
<div id="app">
<child :lists="nameList">
<template slot-scope="a">
{{a}}
</template>
</child>
</div>
<script>
Vue.component('child',{
props:['lists'],
template:`
<div>
<ul>
<li v-for="list in lists">
<slot :bbbbb="list"></slot>
</li>
</ul>
</div>
`
})
let vm = new Vue({
el:'#app',
data:{
nameList:[
{id:1,name:'孙悟空'},
{id:2,name:'猪八戒'},
{id:3,name:'沙和尚'},
{id:4,name:'唐僧'},
{id:5,name:'小白龙'},
]
}
})
</script>
输出结果:
当id等于1的时候,我前面加个你好。
我可以随便根据这个对象的属性值进行操作!
<child :lists="nameList">
<template slot-scope="a">
<div v-if='a.bbbbb.id==1'>你好:<span>{{a.bbbbb.name}}</span></div>
<div v-else>{{a.bbbbb.name}}</div>
</template>
</child>
如果用过elementui的同学,一定知道表格就是这样来的!!