一、什么是slot
当需要让组件组合使用,混合父组件的内容与子组件的模板时,会用到slot,这个过程叫做内容分发。
二、作用域
- 父组件模板内容在父组件作用域内编译。
<div id="app">
<child-component v-show="showChild" />
</div>
<script>
Vue.component('child-component',{
template:'<div>子组件</div>'
})
var app=new Vue({
el:'#app',
data:{
showChild:true
}
})
</script>
这部分内容,我们可以看到,数据showChild是在app这个组件中定义,在注册的组件标签上使用数据。所以,父组件的内容是在父组件的作用域内编译。
- 子组件模板内容在子组件作用域编译
<div id='app'>
<child-component />
</div>
<script>
Vue.component('child-component',{
template:'<div v-show="showChild"></div>',
data:function(){
return{
showChild:true
}
}
})
var app=new Vue({
el:'#app'
})
</script>
这部分内容,我们可以看到,数据在组件child-component中定义,在组件中标签上使用数据。所以,子组件的内容在子组件的作用域内编译。
总结来说就是,父组件中执行父组件的代码,父组件只是引用了子组件这个工具,而子组件的代码在自己内部执行,父子组件互不干扰。
三、匿名solt
在父组件的引用标签中,所写的内容会替换掉子组件slot标签,以及slot标签中的内容。
<div id='app'>
<child-component>
分发的内容
</child-component>
</div>
<script>
Vue.component('child-component',{
template:'(
<div>
<slot>
<p>我是默认slot内容</p>
</slot>
</div>
)'
})
</script>
//运行结果:分发的内容
四、具名slot
给slot指定name后,可以进行多个内容的分发,是具名slot。具名slot可以和匿名slot共存。
<div id='app'>
<child-component>
<h2 slot='header'>我是头部</h2>
<p>我是主内容区域</p>
<div slot='footer'>我是底部</div>
</child-component>
</div>
<script>
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'
})
</script>
/**
运行结果:
<div class='container'>
<div class='header'>
<h2>我是头部</h2>
</div>
<div class='main'>
<p>我是主内容区域</p>
</div>
<div class='footer'>
<div>我是底部</div>
</div>
</div>
**/
五、作用域插槽
作用域插槽,可以复用一个模板来渲染元素,父组件接收来子组件的临时变量props值
<div id='app'>
<child-component>
<template scope='props'>
<p>来自父组件的内容</p>
<p>{{prps.msg}}</p>
</template>
</child-component>
</div>
<script>
Vue.component('child-component',{
template:'(
<div class='container'>
<slot msg='来自子组件的内容'>
</div>
)'
})
var app=new Vue({
el:'#app'
})
</script>
/**
运行结果:
<div id='app'>
<div class='container'>
<p>来自父组件的内容</p>
<p>来自子组件的内容</p>
</div>
</div>
**/