开篇
学习任何内容,再多的话都不如实践来的直接——🌼🌻🌼
初识slot
具名slot
给<slot>
元素指定一个name后可以分发多个内容,具名slot可以与单个slot共存
<div id="app">
<child-component>
<h2 slot="header">标题</h2>
<p>正文内容</p>
<p>更多的正文内容</p>
<div slot="footer">底部信息</div>
</child-component>
</div>
Vue.component('child-component', {
template: '\
<div class="container">\
<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'
})
渲染后的效果:
这里有一个小tips:那就是<div class=main>
内的<slot>
没有name特性,那么它将作为默认slot出现,父组件没有使用slot特性的元素与内容都将在这里出现。
如果没有指定默认的匿名slot,父组件内多余的内容片段就都将被抛弃
作用域slot
<div id="app">
<child-component>
<template scope="props">
<p>来自父组件内容</p>
<p>{{props.msg}}</p>
</template>
</child-component>
</div>
Vue.component('child-component', {
template: '\
<div class="container">\
<slot msg="来自子组件的内容"></slot>\
</div>'
})
var app = new Vue({
el: '#app'
})
这里的props它只是一个传递数据给组件的写法,就像:
v-for="item in items"
里的item一样,父组件中使用了<template>
元素,并且拥有了一个scope="props"的特性,这里的props只是一个临时变量,template可以通过临时变量来访问来自子组件插槽的数据msg,再来看一个经典例子,那就访问数组
作用域插槽典例
<div id="app">
<my-list :books="books">
<!-- 作用域插槽也可以是具名slot -->
<template slot="book" scope="props">
<li>{{props.bookName}}</li>
</template>
</my-list>
</div>
Vue.component('my-list', {
props: {
books: {
type: Array,
dufault: function(){
return [];
}
}
},
template: '\
<ul>\
<slot name="book" \
v-for="book in books"\
:book-name="book.name">\
</slot>\
</ul>'
});
var app = new Vue({
el: '#app',
data: {
books: [
{name: '《实战》'},
{name: '《实战2》'},
{name: '《实战3》'}
]
}
})
分析
访问slot内部信息
用的例子是第一个
<div id="app">
<child-component>
<h2 slot="header">标题</h2>
<p>正文内容</p>
<p>更多的正文内容</p>
<div slot="footer">底部信息</div>
</child-component>
</div>
Vue.component('child-component', {
template: '\
<div class="container">\
<div class="header">\
<slot name="header"></slot>\
</div>\
<div class="main">\
<slot></slot>\
</div>\
<div class="footer">\
<slot name="footer"></slot>\
</div>\
</div>',
mounted: function() {
var header = this.$slots.header;
var main = this.$slots.default;
var footer = this.$slots.footer;
console.log(footer);
console.log(footer[0].elm.innerHTML);
},
})
var app = new Vue({
el: '#app'
})
这里我们使用$slots
来访问具名slot,$slots.default
包括了所有没有被包含再具名slot中的节点。