1、正常情况下,我们在父组件中使用子组件的方式:
父组件引入子组件,并且传递给子组件数据,然后就可以显示出来了
// Prarent.vue
<template>
<div class="hello">
<child :items="programList"></child>
</div>
</template>
<script>
import child from './child'
export default {
name: 'Prarent',
components: {
child
},
data() {
return {
programList: [
{
id: 1,
name: '节目A',
width: 800,
height: 800
},
{
id: 2,
name: '节目B',
width: 500,
height: 500
}
]
}
},
created() {},
mounted() {},
methods: {}
}
</script>
// child.vue
<template>
<ul>
<li v-for="item in items" :key="item.id">{{item.name}}</li>
</ul>
</template>
<script>
export default {
name: 'Child',
components: {},
props: {
items: [Array, Object]
},
data() {
return {}
},
created() {},
mounted() {},
methods: {}
}
</script>
浏览器显示结果:
节目A
节目B
2、默认插槽:就是光秃秃的slot,身上啥都没有。
我在子组件添加一对标签做占位,然后在父组件对应的地方写点东西,就可以连起来显示出来。
// child.vue
<template>
<ul>
<li v-for="item in items" :key="item.id">{{item.name}}<slot></slot></li>
</ul>
</template>
// parent.vue
<template>
<div class="hello">
<child :items="programList">——我是多余的</child>
</div>
</template>
浏览器显示:
节目A ——我是多余的
节目B——我是多余的
3、具名插槽:就是带了一个名字name的slot,方便别人好找。
就算带名字的占位的,父组件派过去的小弟,你们自己按照名字去找座位坐下来。
// child.vue
<template>
<ul>
<li v-for="item in items" :key="item.id">
<div>
<slot name="header"></slot>
</div>
{{item.name}}
<slot></slot>
</li>
</ul>
</template>
<template>
<div class="hello">
<child :items="programList">
——我是多余的默认插槽
<template slot="header">我是具名插槽,我要坐我自己的位置。</template>
</child>
</div>
</template>
浏览器显示:
我是具名插槽,我要坐我自己的位置。
节目A——我是多余的默认插槽
我是具名插槽,我要坐我自己的位置。
节目B——我是多余的默认插槽
备注:v2.6新增v-slot替代老方法, 就是在template标签上用v-slot:插槽名
来绑定具名插槽。
// partent.vue
<template>
<div class="hello">
<!--具名插槽-->
<child :items="programList">
<template v-slot:header>我是向具名插槽提供的数据</template>
</child>
</div>
</template>
4、作用域插槽:就是身上绑定了数据data的slote。
// child.vue
<template>
<ul>
<li v-for="item in items" :key="item.id">
<slot :data="item"></slot>
{{item.width}} - {{item.height}} // 在这里加工数据了
</li>
</ul>
</template>
// parent.vue
<template>
<div class="hello">
<child :items="programList">
<template slot-scope="slotProps">
<span>***</span> // 父组件在这里自定义了东西
{{slotProps.data.name}}
</template>
</child>
</div>
</template>
显示器结果:
// ***是父组件拿到传回来的数据后加工显示的,
// 800-800,500-500这种是子组件在里面加工了。
*** 节目A 800 - 800
*** 节目B 500 - 500
这里有几点说明:
1)slotProps是可以随便取名的, slot-scope=“xxx”,
那么 {{xxx.data.name}}里面就用xxx。
2)slotProps.data这里为什么是data呢? 因为child.vue中<slot :data="item">{{item.name}}</slot>
这里绑定的是data。
如果<slot :HaHa="item">{{item.name}}</slot>
绑定的是HaHa,那么,父组件用的时候,就需要改成{{slotProps.HaHa.name}}
。
备注:v2.6新增v-slot替代slot-scope老方法,
// parent.vue
<template>
<div class="hello">
<child :items="programList">
<template v-slot:default="slotProps">
<span>***</span>
{{slotProps.data.name}}
</template>
</child>
</div>
</template>
这里的default指默认插槽,可以对应其他的header、footer等插槽名称。如果只有默认插槽,default可以省略,简写成v-slot="slotProps
parent.vue
<template>
<div class="hello">
<child :items="programList">
<template v-slot="slotProps">
<span>***</span>
{{slotProps.data.name}}
</template>
</child>
</div>
</template>
就算这么简单,so easy, 麻麻再也不用担心我的学习。
补充说明:为什么有作用域插槽这个奇葩呢?别人写好了一个组件,该组件已经封装好了,但他觉得,数据的显示风格让用户自己定义,一开始最初的数据是我们传进去的,经过别人写好的组件转了一圈,被别人改造了一下(譬如洗了个头,刮了个胡子),再传出来,给用户自己用,用户你再给他穿红色的衣服还是粉色的衣服,用户自己决定吧。