插槽就是子组件中的提供给父组件使用的一个占位符,用 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的标签。
在父组件中引用的子组件的同时,希望在子组件的指定位置插入一段内容,
默认插槽顾名思义就是默认中的,默认的插槽为直接写在子组件标签内部的,在子组件中用slot标签接收
展示的效果
思考: 如果子组件中没有放插槽,同样的父组件中在子组件中填充内容,会出现什么问题?
效果:
总结:
如果子组件没有使用插槽,父组件如果需要往子组件中填充模板或者html, 是没法做到的
具名插槽其实就是给插槽娶个名字。一个子组件可以放多个插槽,而且可以放在不同的地方,而父组件填充内容时,可以根据这个名字把内容填充到对应插槽中。
子组件的代码,设置了两个插槽(header和footer):
父组件填充内容, 父组件通过 v-slot:[name] 的方式指定到对应的插槽中
展示效果
总结:
父组件填充内容时,是可以根据这个名字把内容填充到对应插槽中的,即使父组件对插槽的填充的顺序打乱,只要名字对应上了,就可以正确渲染到对应的插槽中。
作用域插槽其实就是带数据的插槽,即带参数的插槽,简单的来说就是子组件提供给父组件的参数,该参数仅限于插槽中使用,父组件可根据子组件传过来的插槽数据来进行不同的方式展现和填充插槽内容。
使用方法:
子组件存放一个带数据的插槽: userInfo和jobInfo、lookInfo是子组件传给父组件的参数
<template>
<div>
<h3>这是作用域插槽 - 子组件</h3>
<p>作用域插槽内容展示部分</p>
<div>
<h4>
默认插槽,其实默认插槽也是name="default"的一个具名插槽的简写
</h4>
<slot :sonMsg="sonMsg"></slot>
<hr>
<slot name="nameSlot"></slot>
<hr>
<h4>多个参数</h4>
<slot name="userInfo"
:userInfo="{name: name, age, isWeading}"
:jobInfo="{work, workAge, motto}"
:lookInfo="{height, weight}">
</slot>
</div>
</div>
</template>
<script>
export default {
data () {
return {
sonMsg: '这是子组件中的内容信息',
name: '赵二丫',
age: 28,
isWeading: 'No',
work: "程序员",
workAge: "n多年",
motto: "地球不爆炸,我们不放假",
height: '165cm',
weight: '100kg'
}
},
}
</script>
<style lang="scss" scoped>
</style>
父组件通过 老版本(即为vue2.6.0之前的)中使用slot-scope来接收子组件传过来的插槽数据,新版本则更简单,再根据插槽数据来填充插槽的内容
<template>
<div class="conteiner">
<h2>这是作用域插槽 - 作用域插槽父组件</h2>
<p style="color: #f00;">
作用域插槽为在插槽中,为父元素的环境,
想使用子组件环境中的变量,算是插槽的传值方式
</p>
<p>作用域插槽子组件调用,以及作用域插槽的使用</p>
<hr />
<div>
<son>
<template v-slot="sonMsgProp">
<h3>首先是默认插槽</h3>
<div>在父组件中的信息:{{msg}}</div>
<div>这是子组件中的信息: {{sonMsgProp.sonMsg}}</div>
</template>
<template #nameSlot="sonMsgProp">
<h3>然后是具名插槽</h3>
<p>具名插槽的简单使用</p>
<div>在父组件中的信息:{{msg}}</div>
<div>这是子组件中的信息: {{sonMsgProp.sonMsg}}</div>
</template>
<template #userInfo="{userInfo, jobInfo, familyInfo={members: '未知'}, lookInfo: goddesInfo}">
<h3>传入多个参数</h3>
<p>
传入多个参数,可以使用解构的方式传入,
当然也可以设置默认值和设置别名,在传入的值不存在时候会用默认的值
</p>
<dl>
<dt>个人信息</dt>
<dd>姓名:{{userInfo.name}}</dd>
<dd>年龄:{{userInfo.age}}</dd>
<dd>已婚:{{userInfo.isWeading}}</dd>
</dl>
<dl>
<dt>工作信息</dt>
<dd>工作:{{jobInfo.work}}</dd>
<dd>工龄:{{jobInfo.workAge}}</dd>
<dd>格言:{{jobInfo.motto}}</dd>
</dl>
<dl>
<dt>家庭情况</dt>
<dd>家庭成员:{{familyInfo.members}}</dd>
</dl>
<dl>
<dt>身体情况</dt>
<dd>升高:{{goddesInfo.height}}</dd>
<dd>体重:{{goddesInfo.weight}}</dd>
</dl>
</template>
</son>
</div>
</div>
</template>
<script>
import Son from './Son.vue';
export default {
components: {
Son,
},
data () {
return {
msg: '这是父组件中的信息'
}
},
}
</script>
<style lang="scss" scoped>
</style>
如果子组件中的某一部分的数据,每个父组件都会有自己的一套对该数据的不同的呈现方式,这时就需要用到作用域插槽。