顾名思义,在父组件引用子组件时,往里面插别的东西
<child-component>
<p>组件里插进去的别的东西</p>
</child-component>
插槽内容
先看一眼
<template>
<div>
<p>这是父组件</p>
<child-component>
<p>我插进来了</p>
</child-component>
</div>
</template>
---------------------------------------------------------------------
<template>
<div>
<p>这是子组件</p>
<slot></slot> <!-- 结果 <p>我插进来了</p> 替换掉 <slot></slot> -->
</div>
</template>
在父组件中使用的子组件 child-component ,中间写了个p标签,
相对应的,在子组件中写了个<slot></slot>标签,
这就是了,这个p标签就是你要插入的东西,slot标签是你要插入dom的位置,是不是很简单,这个p标签就是你要往子组件中插入的内容,slot插槽就是接收这个内容的。
并且,这个内容可以是任何其他的模板代码,其他的组件也都是可以的,但是如果子组件中没有slot标签来渲染传过来的东西,那父组件传过来的任何内容都会被丢弃
看上面小红猪,也就是说箭可以是任何东西,但必须有靶子,不然没目的地,箭就丢了,靶子在什么地方箭就会射到什么地方,
后备内容 / 默认内容
上面有一种情况是缺少 slot(靶子) 会出现什么情况,下面这种情况相反,是缺少内容(箭)
<template>
<div>
<p>这是父组件</p>
<child-component>
啥也没有
</child-component>
</div>
</template>
---------------------------------------------------------------------
<template>
<div>
<p>这是子组件</p>
<slot><p>我是默认内容</p></slot> // 结果 显示插槽slot的默认内容 <p>我是默认内容</p>
</div>
</template>
可以为slot设置一个默认内容,如果我在父组件中使用了子组件,但是没有提供插槽内容,这样插槽slot就会渲染他的默认内容,如果在父组件中提供了插槽的内容,就会渲染你提供的插槽内容。
具名插槽
有时我们需要用到多个插槽,为了应对这种情况,slot 提供了一个属性 name ,这个属性可以用来定义额外的插槽,看代码
<template>
<div>
<p>这是父组件</p>
<child-component>
<template v-slot:aaa>
<h1>我是aaa里面的内容</h1>
</template>
<h1>我是没有指定slot的内容</h1>
<h1>我也是</h1>
<template v-slot:bbb>
<h1>我是bbb里面的内容</h1>
</template>
</child-component>
</div>
</template>
---------------------------------------------------------------------
<template>
<div>
<p>这是子组件</p>
<div id="box1">
<slot name="aaa"></slot>
</div>
<div id="box2">
<slot></slot>
</div>
<div id="box3">
<slot name="bbb"></slot>
</div>
</div>
</template>
结果是
<template>
<div>
<p>这是子组件</p>
<div id="box1">
<h1>我是aaa里面的内容</h1>
</div>
<div id="box2">
<h1>我是没有指定slot的内容</h1>
<h1>我也是</h1>
</div>
<div id="box3">
<h1>我是bbb里面的内容</h1>
</div>
</div>
</template>
看得出来,具名插槽就是在需要多个 slot 的时候,给每个内容一个名字,他们根据名字去找属于他们的插槽在哪个位置。
<template>标签中加上v-slot 对应要去的插槽的名字,<template> 里的所有内容都会被视为插槽的内容。
为啥中间那俩 H1 知道该去哪个插槽?
这个slot 我们没有去规定一个name,但他会有一个默认的name = default,所有没被带有v-slot的<template>包裹起来的元素,都会被视为他的内容,
具名插槽同样可以设置默认值,在template里的内容为空的时候渲染,如果<slot name="bbb"></slot>找不到和他name对应的<template v-slot:bbb>,则会被丢弃。
具名插槽缩写
<template v-slot:aaa>
<h1>我是aaa里面的内容</h1>
</template>
等于
<template #aaa>
<h1>我是aaa里面的内容</h1>
</template>
v-slot: 可以缩写为#
作用域插槽
我们可以在父组件编写插槽内容的时候使用子组件中的数据,这里和父组件像自组件传值是比较像的,
<span>
<slot name="aaa" v-bind:user="user" v-bind:userTwo="userTwo">
{{ user.name}}
</slot>
</span>
子组件内
data(){
user:{
name:'一号',
age:18
}
userTwo:{
name:'二号',
age:188
}
}
<child-user>
<template v-slot:aaa="slotProps"> 可以简写 #aaa = "slotProps"
{{ slotProps.user.name }}
{{ slotProps.userTwo.name }}
</template>
</child-user>
父组件内
没啥好说的,子组件这边传过去,父组件那边模板 绑定这个插槽aaa,给包含所有插槽 prop 的对象命名 slotProps (随便起个你喜欢的名字),然后用就行了。
这是2.6.0之后的,开始使用的v-slot
累死我了我不写了,看到这你应该大体就明白了,想更深入了解再去看看vue文档吧。