首先思考:为什么要使用slot? slot解决了什么问题?
首先,父组件可以给子组件传递数据,但却不能传递DOM节点或者是组件,为了解决这个问题,slot诞生了。
slot 是Vue的内置组件,也就是我们俗称的插槽。(联想:电源插板上有好多小孔)
slot其实就是父组件传递的DOM结构;
当组件渲染的时候,定义在子组件模板中的 元素将会被替换为内容中的内容,这个内容可以是多个DOM节点,也可以是其他组件
详情可查看官网解释:https://cn.vuejs.org/v2/guide/components-slots.html
1.单个slot (也就是匿名插槽)
<slot>默认插槽,如果不提供任何内容则显示</slot>
<slot name="default">默认插槽,如果不提供任何内容则显示</slot>
一个不带 name 的 出口会带有隐含的名字“default”。
在 MyTestInSlot.vue 文件中:
<template>
<div>
<slot>默认插槽</slot><!--在子组件中-->
</div>
</template>
然后在 父组件 MySlotParentTwo.vue 中
<template>
<div class="container">
<my-test-in-slot ></my-test-in-slot>
</div>
</template>
则此时会显示:默认插槽
而如果在组件中加入内容:
<template>
<div class="container">
<my-test-in-slot >
<h2>222</h2>
</my-test-in-slot>
</div>
</template>
则 ‘默认插槽’ 会被替换为 ‘222’
2.具名插槽: slot 组件有个name 选项(或着叫属性) 可以给这个slot 起个名字(要不然好多插槽,你知道哪个要插到哪个里面去,所以就起个名字作为标识)
有时候我们会给子组件传多个DOM,有时甚至还会对多个DOM的顺序做出要求,
为了解决以上问题,我们为每个DOM起名,即具名插槽。
<template>
<div>
<slot name="header">
<h2>header</h2>
</slot>
<slot name="main">
<h2>main</h2>
</slot>
<slot name="footer">
<h2>footer</h2>
</slot>
<slot name="other">
<h2>other</h2>
</slot>
</div>
</template>
写法:<slot name="header"></slot>
然后在父组件中用指令:v-slot一一去映射每个slot模板
<template>
<div class="container">
<my-test-in-slot>
<template v-slot:header>
<h2>Here is header</h2>
</template>
<template v-slot:main>
<h2>Here is main</h2>
</template>
<template v-slot:footer>
<h2>Here is footer</h2>
</template>
<!--当然可以简写为: #other-->
<template v-slot:other>
<h2>Here is other</h2>
</template>
</my-test-in-slot>
</div>
</template>
渲染的结果:
注意 v-slot 指令只能添加在<template> 上
3.作用域插槽(就是可以传递数据的插槽)
作用域插槽使得在父组件中可以访问插槽中来自子组件的数据
在子组件 MyTestInSlot.vue 文件中使用v-bind指令动态绑定两个属性:myName, author这两个属性将在父组件的插槽模板中使用
<template>
<div>
<!--给插槽动态绑定属性: myName-->
<slot :myName="nickName"></slot>
<!--给插槽动态绑定属性: author-->
<slot :author="myAuthor"></slot>
</div>
</template>
<script>
export default {
data () {
return {
nickName: '外号',
myAuthor: '作者'
}
}
}
</script>
然后在父组件中可以用传递过来的作用域变量来获取子组件的属性值
<template>
<div class="container">
<my-test-in-slot>
<!-- slot-scope 已经在vue 2.6.0以后废弃了,
所以现在可以用v-slot指令,只能作为template的属性使用,props是一个别名,
可以随便命名,这里props已经相当于拿到子组件的实例了,
所以可以直接props.xxx来访问子组件的属性-->
<template v-slot:default="props">
<h1>{{ props.myName }}</h1>
<h1>{{ props.author }}</h1>
</template>
</my-test-in-slot>
</div>
</template>