什么是插槽
官方解释:<slot>
元素作为组件模板之中的内容分发插槽。<slot>
元素自身将被替换
也就是说,当父组件使用子组件时候,可以用插槽的方式,将内容分布出去,子组件中,用<slot>来接收父组件传过来的dom进行显示。
插槽的三种不同使用
1.普通使用,没有命名对应名字
代码:
//父组件
<div id="app">
<Child>
<div>无</div>
<div>还有</div>
<div>没有</div>
</Child>
</div>
//后面例子,这个就省略不写了
<script type="text/javascript">
new Vue({
el: '#app',
data: {},
components: {
Child: {
template: '#child'
}
}
})
</script>
//子组件
<template id="child">
<div>
<div class="panel">
<div class="content">这是内容这是内容</div>
<slot></slot>
</div>
</div>
</template>
结果显示:
由此可见,父组件中使用子组件,并且使用slot来分配内容&&没有命名名字,如果子组件template模板中有<slot>标签,则不管父组件传入有几个,都会被显示出来。(仅限是没有具名的插槽)
2.具名的插槽
顾名思义,就是在分布内容的插槽了,定义一个name名字,这样就可以一一对应
缩写:可以将v-solt替换成字符#
代码:
<!-- //父组件 -->
<div id="app">
<Child>
<template v-slot:header>
<div>这是头</div> //有加名字的slot插槽
</template>
<template v-slot:default>
<div>这是头</div>
<div>这是头</div>
<div>这是头</div>
</template>
<template v-slot:footer>
<div>这是尾</div> //有加名字的slot插槽
</template>
<!-- 具名插槽名字缩写 -->
<template #header>
<div>这是尾</div>
</template>
</Child>
</div>
<!-- //子组件 -->
<template id="child">
<div>
<div class="panel">
<div class="content">这是内容这是内容</div>
<slot name="footer"></slot>
<slot name="header"></slot>
<!-- <slot></slot> -->
</div>
</div>
</template>
结果显示:
由此可见,父组件用具名的插槽,在子组件中接收显示的时候,具体dom显示位置跟子组件中<slot>元素标签设置的位置有关,跟父组件中设置的没有关联;而且,没有命名的插槽,如果子组件中如果没有用<slot></slot>空标签接收它,是不会显示的
第二种情况
父组件不变,子组件如下
代码:
<template id="child">
<div>
<div class="panel">
<div class="content">这是内容这是内容</div>
<slot name="header"></slot>
<slot></slot>
<slot></slot>
</div>
</div>
</template>
结果显示:
可以看出,具名的插槽,如果子组件没有设置一个对应名字的<slot>,那么父组件设置的具名插槽是不会显示,即使有无名字的<slot>;其次父组件中发布的无命名的插槽内容,在子组件中<slot></slot>就包含显示全部,有两个这样,就显示两遍。
3.动态插槽
动态指令参数在 v-slot
上也是有效的。
使用场景:父组件想自定义子组件名称,可以在使用子组件的时候,通过props传值过去;子组件获取到值,将其动态绑定在标签上,如:<slot :name="name">
即可以定义下面这样的动态插槽名:
//父组件
<Child :dynamicSlotName = "dynamicSlotName">
<template v-slot:[dynamicSlotName]>
...
</template>
<!-- 缩写为 -->
<template #[dynamicSlotName]>
...
</template>
</Child>
<script>
export default {
data() {
return {
dynamicSlotName: 'wht'
}
}
}
</script>
//子组件
<template id="child">
<div>
<div class="panel">
<slot :name="dynamicSlotName"></slot>
</div>
</div>
</template>
<script>
export default {
porps: {
dynamicSlotName: String
}
}
</script>
4.作用域插槽
当我们希望提供的组件带有一个可从子组件获取数据的可复用的插槽,就可以用到。
作用域插槽的关键之处就在于,父组件能接收来自子组件的slot传递过来的参数
在下面这个例子中,子组件是个信息列表模块,item在不同的父组件中获取的state不同,可以使用作用域组件实现
代码:
//子组件
<div class="box" v-for="item of list" :key="item.id">
<div class="box-title">
<p>
<span>{{item.deNo}}</span>
<!--我们为每个item准备了一个插槽,将item对象作为一个插槽的prop传入-->
<slot class="genre" v-bind:item="item"></slot>
</p>
<p>{{item.deDate}}</p>
</div>
</div>
//父组件
<Child>
<!--1.插槽必须是template开头和结尾的内容-->
<!--2.v-solt="props"声明从子组件传递的数据都放在props里,传给父组件 -->
<!-- 3.如果有具名,则v-solt:header="props"-->
<template v-slot="props">
<span class="genre">{{props.item.state}}</span>
</template>
</Child>
//另一种写法 ,结构
<div>
<template #default="{state}">
<span class="genre">{{state}}</span>
</template>
</div>
//如果是默认插槽,可用独占默认插槽缩写
<Child v-slot="props">
<template >
<span class="genre">{{props.item.state}}</span>
</template>
</Child>
有什么错误或者知识,可以私信交流哦!!!