由于本人刚接触vue,本文章写的自己对slot的理解,欢迎大家进行指正。
一、对slot的理解
我理解的slot就是一个占位符,定义组件时,为了实现组件复用,定义一个slot插槽,然后父组件调用子组件时,可以根据请求的内容灵活的设置slot,这样一个组件就可以被多个页面复用。
二、作用域
父组件模板的内容是在父组件作用域内编译的,子组件模板的内容是在子组件作用域内编译的。例如:
<div id="app">
<child-componetnt v-show="showChild"></child-componetnt>
</div>
这里的状态showChild绑定的是父组件的数据,如果想在子组件上绑定,应该是:
Vue.component('child-component',{
template:'<div v-show='showChild'>子组件</div>',
data:function(){
return{
showChild:true
}
}
})
因此,slot分发的内容,作用域是在父组件上的。
三、slot用法
slot用法是一般分为单个slot和具名slot,两个可以共存。
单个slot
<div id="app">
<child-component>
<p>分发的内容</p>
<p>更多分发的内容</p>
</child-componetnt>
</div>
<script>
Vue.component('child-component',{
template:'<div><slot><p>如果父组件没有插入内容,我将作为默认出现</p></slot></div>'
})
var app=new Vue({
el:'#app'
})
</script>
子组件在child-component的模板内定义了一个<slot>元素,并且用一个<p>作为默认的内容,在父组件没有使用slot时,会渲染这段默认的文本;如果写入了slot,那就会替换整个<slot>。
具名slot
<div id="app">
<child-component>
<h2 slot="header">标题</h2>
<p>分发的内容</p>
<p>更多分发的内容</p>
<div slot="footer">底部信息</div>
</child-componetnt>
</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>
子组件中声明了3个<slot>元素,其中在<div class="main">内的<slot>没有使用name特性,它将作为默认slot出现,父组件没有使用slot特性的元素与内容都将出现在这里。
如果没有指定默认的匿名slot,父组件内多余的内容片段都将被抛弃。
四、作用域插槽
作用域插槽就是一种特殊的slot,使用一个可以复用的模板替换已渲染的元素。概念比较难理解,我们来看一下例子:
<div id="third">
<child-componetnt>
<template scope="props">
<p>来自父组件的内容</p>
<p>{{props.msg}}</p>
</template>
</child-componetnt>
</div>
Vue.component('child-componetnt', {
template: '\
<div class="container">\
<slot msg="来自子组件的内容"></slot>\
</div>'
});
观察子组件的模板,在<slot>元素上有一个类似props传递数据给组件的写法 msg=“xxx”,将数据传到了插槽。父组件中使用了<template>元素,而且拥有一个scope=“props”的特性,这里的props只是一个临时变量,就像v-for=“item in items”里面的item一样。template内可以通过临时变量props访问来自子组件插槽的数据msg。
作用域的插槽的使用场景就是既可以复用子组件的slot,又可以使slot内容不一致。
props传递数据、events触发事件和slot内容分发就构成了Vue组件的3个API 来源,events可以触发原生DOM。