插槽
插槽就是子组件提供给父组件的占位符,用slot来表示,父组件可以在这个占位符中填充各种的模板代码。
为什么要使用插槽?
你可能不太明白为什么要给子组件传入HTML而不是直接写在子页面中内,如果出现这种情况,你有五个子页面这五个子页面只有一小部分内容不一样。你会怎么做呢?最笨的办法就是复制代码,但在Vue中更加简便的方法就是插槽。
插槽的分类:
普通插槽、具名插槽、作用域插槽
普通插槽
子组件son.vue:
<template>
<div>
<slot></slot>
</div>
</template>
父组件
<template>
<div>
<p>我是父组件</p>
<Son>
验证插槽是否生效 //用son组件标签包裹内容,验证slot
</Son>
</div>
</template>
<script>
import Son from './son.vue'
export default {
name:'parent',
components:{
Son
}
</script>
具名插槽
具名插槽就是每个插槽带有自己的名字,在父组件中用到v-slot
,也可以直接缩写为#
子组件:
<template>
<div class="about">
<h1>子组件</h1>
<!--普通插槽-->
<slot></slot>
<!-- 给插槽加了个name属性,就是所谓的具名插槽了 -->
<slot name="one"></slot>
<slot name="two"></slot>
</div>
</template>
父组件
<template>
<div class="about">
<h1>父组件</h1>
<children>
<template v-slot:one>
<p>one插槽</p>
</template>
<template v-slot:two>
two插槽
</template>
</children>
</div>
</template>
作用域插槽
作用域插槽可以传递参数。
子组件
<template>
<div class="about">
<h1>This is an Children page</h1>
<slot :obj1="obj1" name="one"></slot>
<slot :obj2="obj2" name="two"></slot>
</div>
</template>
<script>
export default {
data () {
return {
obj1: {
name: 'one slot'
},
obj2: {
name: 'two slot'
}
}
}
}
</script>
父组件
<template>
<div class="about">
<h1>This is an Parent page</h1>
<children>
<template v-slot:one="slotProps">
<h2>{
{
slotProps.obj1.name}}</h2>
</template>
<template v-slot:two="twoSlotProps">
<h2>{
{
twoSlotProps.obj2.name}}</h2>
</template>
</children>
</div>
</template>
<script>
import Children from './Children.vue'
export default {
components: {
Children
},
data () {
return {
}
}
}
</script>
动态插槽
动态指令参数也可以用在 v-slot 上,来定义动态的插槽名.
子组件:
<template>
<div class="about">
<h1>This is an Children page</h1>
<slot :obj="obj1" name="one"></slot>
<slot :obj="obj2" name="two"></slot>
</div>
</template>
<script>
export default {
data () {
return {
obj1: {
name: 'one slot'
},
obj2: {
name: 'two slot'
}
}
}
}
</script>
父组件:
<template>
<div class="about">
<h1>This is an Parent page</h1>
<children>
<template v-slot:[dynamicSlotName]="slotProps">
<h2>{
{
slotProps.obj.name}}</h2>
</template>
</children>
</div>
</template>
<script>
import Children from './Children.vue'
export default {
components: {
Children
},
data () {
return {
dynamicSlotName: 'one'
}
}
}
</script>
总结
slot又名插槽,是Vue的内容分发机制,组件内部的模板弓|擎使用slot元素作为承载分发内容的出口。插槽slot是子组件的一个模板标签元素,而这一个标签元素是否显示,以及怎么显示是由父组件决定的。
slot又分三类,默认插槽,具名插槽和作用域插槽。
- 默认插槽:又名匿名插槽,当slot没有指定name属性值的时候一个默认插槽,一个组件内只有一个匿名插槽。
- 具名插槽:带有具体名字的插槽, 也就是带有name属性的slot, 一个组件可以出现多个具名插槽。
- 作用域插槽:默认插槽、具名插槽的一个变体,可以是匿名插槽,也可以是具名插槽,该插槽的不同点是在子组件渲染作用域插槽时,可以将子组件内部的数据传递给父组件,让父组件根据子组件的传递过来的数据决定如何渲染该插槽。
实现原理:当子组件vm实例化时,获取到父组件传入的slot标签的内容,存放在vm. $slot
中,默认插槽为vm. $slot .default
,具名插槽为vm. $slot.xxx
, xx为插槽名,当组件执行渲染函数时候,遇到slot标签,使用$slot
中的内容进行替换,此时可以为插槽传递数据,若存在数据,则可称该插槽为作用域插槽。