使用情形:
当子组件除了 template 中内容,还需要再展示父组件传过来的内容时。(当子组件有一部分内容是根据父组件传递过来的 dom 进行显示时,就使用到了插槽)
通过插槽可以更方便的向子组件传递 dom 元素。
<div id="app">
<child>
<p>word</p>
</child>
</div>
<script>
Vue.component("child", {
template: `<div>
<p>hello</p>
<slot></slot>
</div>`
})
var vm = new Vue({
el: "#app"
})
</script>
同时,还可以设置插槽的默认值,当父组件不传递 dom 元素时,显示 slot 默认值。
<div id="app">
<child></child>
</div>
<script>
Vue.component("child", {
template: `<div>
<p>hello</p>
<slot>default slot</slot>
</div>`
})
var vm = new Vue({
el: "#app"
})
</script>
具名插槽:
要实传入的dom 元素按照需求排列。当使用以下方法时,肯定不适合。
<div id="app">
<app-content>
<div class="header">header</div>
<div class="footer">footer</div>
</app-content>
</div>
<script>
Vue.component("app-content", {
template: `<div>
<slot></slot>
<div class="content">content</div>
<slot></slot>
</div>`
})
var vm = new Vue({
el: "#app"
})
</script>
页面显示如下:
此时会将传进来的 dom 元素按照整体进行渲染。
解决方法:使用具名插槽
<div id="app">
<app-content>
<div class="header" slot="header">header</div>
<div class="footer" slot="footer">footer</div>
</app-content>
</div>
<script>
Vue.component("app-content", {
template: `<div>
<slot name="header"></slot>
<div class="content">content</div>
<slot name="footer"></slot>
</div>`
})
var vm = new Vue({
el: "#app"
})
</script>
在需要传进来的 dom
元素上给相应的节点添加不同的 slot
属性名,然后在子组件中使用 slot
标签并定义对应的 name
属性进行绑定。
具名插槽也可以使用默认值:
<div id="app">
<app-content>
<div class="footer" slot="footer">footer</div>
</app-content>
</div>
<script>
Vue.component("app-content", {
template: `<div>
<slot name="header">
<h1 class="header">defalut header</h1>
</slot>
<div class="content">content</div>
<slot name="footer"></slot>
</div>`
})
var vm = new Vue({
el: "#app"
})
</script>
插槽只能有一个,而具名插槽可以有多个
作用域插槽
父组件调用子组件时,给子组件传了一个插槽,子组件可以向父组件的插槽里传数据,这个插槽叫做作用域插槽,必须是包含在 template 中,同时申明从子组件接收的数据都放在哪 slot-scope=""
,同时还要告诉子组件模板的信息。
<div id="app">
<child>
<template slot-scope="content">
<h6>{{content.listitem}}</h6>
</template>
</child>
</div>
<script>
Vue.component("child", {
data: function(){
return {
list: [1, 2, 3, 4]
}
},
template: `<div>
<ul>
<slot v-for="item in list" :listitem = item></slot>
</ul>
</div>`
})
var vm = new Vue({
el: "#app"
})
</script>
适应场景:
当子组件做循环,或者子组件某一部分 dom 结构需要从外边传递进来时。