插槽slot:本质就是向组件传递一个DOM。
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.panel{
border: 1px solid #ececec;
}
.panel>*{
padding:10px;
}
.title{
border-bottom: 1px solid #ececec;
}
.content{
border-bottom: 1px solid #ececec;
}
.footer{
}
</style>
</head>
<body>
<div id="app">
<panel>
<div slot="title">YO</div>
<div slot="content">
YO
yo
</div>
<div slot="footer">更多信息</div>
</panel>
</div>
<template id="panel-tpl">
<div class="panel">
<div class="title">
<slot name="title"></slot>
</div>
<div class="content">
<slot name="content"></slot>
</div>
<div class="footer">
<slot name="footer"></slot>
</div>
</div>
</template>
<script src="../lib/vue.js"></script>
<script src="./js/main.js"></script>
</body>
</html>
main.js:
Vue.component('panel', {
template: '#panel-tpl'
})
new Vue({
el: '#app'
})
作用域插槽:
父组件通过props向子组件传值,作用域插槽差不多是父子组件传值的反用,是父组件接收来自子组件的slot标签上通过v-bind绑定进而传递过来的数据。
应用场景:父组件对子组件的内容进行加工处理。
写作用域插槽之前,先介绍一下Vue中的slot内容分发:
<div id="app">
<child-component>
<template slot-scope="props">
<p>分发的内容</p>
<p>更多分发的内容</p>
</template>
</child-component>
</div>
<script>
Vue.component("child-component", {
template: `<div class="container">
<slot><p>父组件如果没有插入内容,我将被显示</p></slot>
</div>`
})
let vm = new Vue({
el: '#app'
})
</script>
如果<child-component></child-component>标签之间没有插入那两个p标签的话,页面会显示子组件模板中定义的“<p>父组件如果没有插入内容,我将被显示</p>”这一则内容,但如果<child-component></child-component>标签之间有插入内容的话,则子组件模板中的<slot></slot>标签以及之间的内容都会被替换成<child-component></child-component>标签之间插入的内容。
这里子组件<slot>内的备用内容,作用域是子组件本身。
作用域插槽:
<div id="app">
<child-component>
<template slot-scope="props">
<p>父组件的数据</p>
<p>{{props.msg}}</p>
</template>
</child-component>
</div>
<script>
Vue.component("child-component", {
template: `<div class="container">
<slot msg="子组件的数据"></slot>
</div>`
})
let vm = new Vue({
el: '#app'
})
</script>
显示结果:
template内可以通过临时变量props来访问来自子组件插槽的数据msg 。
作用域插槽更具代表性的用例是列表组件:
<div id="app">
<child-component :books="books">
<template slot="book" slot-scope="props">
<li>{{props.boonName}}</li>
</template>
</child-component>
</div>
<script>
Vue.component("child-component", {
props: {
books: {
type: Array,
default: function(){
return []
}
}
},
template: `<ul class="container">
<slot name="book" v-for="book in books" :boonName="book.name"></slot>
</ul>`
})
let vm = new Vue({
el: '#app',
data: {
books: [
{name: '《vue.js实战》'},
{name: '《JavaScript》高级程序设计'},
{name: '深入浅出Webpack'}
]
}
})
</script>
子组件<child-component></child-component>接受一个父组件传过来的books数组。并且将它在name为book的slot上使用v-for循环,同时暴露变量bookName,父组件的child-component标签内就可以通过props.bookName访问到绑定的数据;
作用域插槽的使用场景:既可以复用子组件的slot,又可以使slot内容不一致;