什么是插槽
插槽就是子组件提供给父组件使用的一个占位符,用<slot></slot>
表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的<slot></slot>
标签。
插槽分类
-
单个插槽(匿名插槽)
单个插槽可以放置在组件的
任意位置
,但是就像它的名字一 样,一个组件中只能有一个该类插槽
。<slot></slot>
里面可以设置内容,这个内容是保证引入组件的时候,有个默认值。<slot></slot>
里面也可以不设置内容,这样只是没有默认值,是不会报错的。只要组件中有
<slot></slot>
,并且不管有多少个,都会全部渲染为传过来的内容。如果传递的内容,没有slot 来接收,那么,传递的内容就会被抛弃掉,不会起作用。
//父组件
<template>
<div class="parent">
<h3>我是父组件</h3>
<child> <!--子组件 -->
<ul> <!--因为在child子组件中定义了一个<slot></slot> ul中的内容就会显示到插槽中 -->
<li>选项一</li>
<li>选项二</li>
<li>选项三</li>
</ul>
</child>
</div>
</template>
<script>
import child from './child.vue'
export default {
name: 'parent',
data() {
return {
}
},
components:{
child
}
}
</script>
<style scoped>
.parent{
margin-left: 100px;
width: 200px;
background: lightblue;
margin-top: 20px;
}
</style>
//子组件
<template>
<div class="child">
<h3>这里是子组件</h3>
<slot></slot> <!--插槽-->
</div>
</template>
<script>
export default {
name: 'child',
data() {
return {
}
}
}
</script>
<style scoped>
</style>
渲染结果:
2. 具名插槽
简单来说,就是带有name属性的插槽,具名的插槽可以在组件中出现多次
,而之前的匿名插槽只能出现一次。
- 引入组件的页面,如果是多个内容,需要用template包裹起来,并且添加 slot 属性和自定义值 。
slot 的值
需要和组件中<slot name='xxx'></slot> name的值
相对应。- 如果 slot 设置为default 和 name 设置为default,那就和没设置slot与name是一样的。
//父组件
<template>
<div>
<Slot>
<!-- 具名插槽 -->
<!--2.6.0以前的写法-->
//<p style="color:red" slot=header>在首页写入二内容</p>
<!--2.6.0之后的写法-->
<!--<template v-slot:header>
<p>新写法</p>
</template> -->
<template #header>
<p>第二种新写法</p>
</template>
<p style="color:red" slot="main">在首页写入三内容</p>
<p style="color:red" slot="footer">在首页写入一内容</p>
</Slot>
</div>
</template>
<script>
import Slot from './Slot.vue'
export default {
components:{
Slot
},
data(){
return {
}
}
}
</script>
//子组件
<template>
<div>
子组件包含三个插槽
<!-- 具名插槽,header、footer、main -->
<slot name="header"></slot>
<slot name="main"></slot>
<slot name="footer"></slot>
</div>
</template>
<script>
export default {
// name:'slotTwo',
data(){
return {
}
},
}
</script>
渲染效果:
3. 作用域插槽
- 作用域插槽主要是
使用子组件的任何数据来达到自定义显示内容
的目的 - 作用域插槽最最最最最重要的一步,即是在
<slot></slot>上绑定数据
,如果没有绑定数据,则父组件收到的,只是一个空对象{ }。 - 作用域插槽中
<slot></slot>
上绑定数据,可以是写死的,也可以是动态绑定的。如果是动态绑定的,则需要 v-bind:xxx - 作用域插槽中
<slot></slot>
上绑定的数据也可以传一个定义好的有返回值的 methods 方法。 - 当绑定上数据之后,引用组件的地方就能通过
slot-scope
来获取。获取到的内容,就是一个对象。 slot-scope
可以接收任何有效的可以出现在函数定义的参数位置上的JavaScript 表达式
//子组件
<template>
<div>
<!-- 作用域插槽 -->
<!-- 子组件使用:data绑定需要的值 -->
<slot name="myUser" :data="user"></slot>
//绑定一个Methods
<slot name="msg" :Msg='message()'></slot>
</div>
</template>
<script>
export default {
data(){
return {
user:[
{name:'jack',age:18},
{name:'tom',age:19},
{name:'jerry',age:20}
],
message:function(){
return 'hello world'
}
}
},
}
</script>
//父组件
<template>
<div>
<Slot>
<!-- 作用域插槽 -->
<!-- 父组件使用slot-scope,user.data就是子组件传过来的值 -->
<!-- 2.6.0之前的写法 -->
<!-- <template slot="myUser" slot-scope="user">
<p v-for="(item,index) in user.data" :key="index">
{{item}}
</p>
</template> -->
<!-- 2.6.0之后的写法 -->
<template v-slot:myUser='user'>
<p v-for="(item,index) in user.data" :key="index">
{{item}}
</p>
//接受methods的插槽
<template slot='msg' slot-scope="message">
{{message.Msg}}
</template>
</Slot>
</div>
</template>
<script>
import Slot from './Slot.vue'
export default {
components:{
Slot
},
data(){
return {
}
}
}
</script>
渲染效果:
2.6版本之后新用法
- 具名插槽
- slot=’ xxx '改成了 v-slot : xxx 并且冒号后面的名称不带引号
- 组件页面中slot的内容没有变化
- 2.6.0 之后具名插槽
v-slot:header
可以缩写为#header
- 作用域插槽
-
两个属性合并成了一个 v-slot : 插槽名称 = ’ 要传的数据 ’ 。
-
组件页面中slot的内容没有变化 。
-
v-slot 不能用在 html 标签上 。
-
如果是默认插槽 可以写成 v-slot=‘xxx’。
提示:*以上新用法在上面代码中有展示*