*在项目中,时不时会遇到一种情况即:在组件标签内再展示一些内容,默认是不会生效的,需要加上<template slot-scope= 'scope'></template>才生效,一直这么稀里糊涂的用,也不太好,故最近翻阅许多书籍并加以实践,最终彻底搞懂其内部流程,特此记录在这
*大白话就不说了,直接进入主题吧
1、slot是在子组件中写入的,一旦走进组件标签(父组件中引入的子组件)内部,其显示内容的顺序就由组件标签(父组件中引入的子组件)决定
2、slot插槽显示的内容由父组件进行控制;插槽显示不显示和显示顺序由子组件控制
*以上是总的概括,下面就是代码解释,可能会更清楚一点
1、匿名插槽
父组件:父组件在引入的Children子组件里面又放了一堆内容,其这堆内容的显示将会依照子组件内部的顺序依次执行显示
<template>
<div class="hello">
<p>第一个显示的</p>
<Children>
<p>第三个显示的</p>
<p>第四个显示的</p>
<chilchildren></chilchildren>
<p>第五个显示的</p>
</Children>
</div>
</template>
<script>
import Children from '@/components/children'
import chilchildren from '@/components/chilchildren'
export default {
components: {
Children,
chilchildren,
},
}
</script>
子组件: 此组件放了二个匿名插槽,意味着将在父组件里面引入的子组件内部的内容显示两次
<template>
<div class="slotOne">
<p>第二个显示的</p>
<slot></slot>
<p>第六个显示的</p>
<!-- 注意这里又放了一个匿名插槽,意味着将在父组件里面引入的子组件内部的内容显示两次 -->
<slot></slot>
<p>第七个显示的</p>
</div>
</template>
效果图:其中红框圈出的两部分就是子组件定义的两个slot
2、具名插槽
父组件:使用v-slot或者#(是v-slot的缩写)或者slot(v3.0已废弃这种写法)来对应子组件的某个插槽
<template>
<div class="hello">
<p>第一个显示的</p>
<Children>
<!-- <template v-slot:one> v-slot和#只能在template中写入-->
<template #one>
<p>第三个显示,因为对应子标签name为one的slot</p>
</template>
<p>
特别注意:因为在子标签没有对应的匿名slot,故这下此内容和下面的子子标签就不会显示了
</p>
<chilchildren></chilchildren>
<p slot="two">第五个显示,因为对应子标签name为two的slot</p>
</Children>
</div>
</template>
<script>
import Children from '@/components/children'
import chilchildren from '@/components/chilchildren'
export default {
components: {
Children,
chilchildren,
},
}
</script>
子组件:使用name属性来区分各个插槽,方便在父组件进行调用
<template>
<div>
<p>第二个显示的</p>
<slot name="one"></slot>
<p>第四个显示的</p>
<slot name="two"></slot>
</div>
</template>
效果图:
父组件:
<template>
<div class="hello">
<p>第一个显示的</p>
<Children>
<template slot="one">
<p>第三个显示,因为对应子标签name为one的slot</p>
</template>
<p>
第五个显示的,特别注意:因为在子标签有了相对应的匿名slot,故这下此内容和下面的子子标签就显示了
</p>
<chilchildren></chilchildren>
<p slot="two">第七个显示</p>
</Children>
</div>
</template>
<script>
import Children from '@/components/children'
import chilchildren from '@/components/chilchildren'
export default {
components: {
Children,
chilchildren,
},
}
子组件:
<template>
<div>
<p>第二个显示的</p>
<slot name="one"></slot>
<p>第四个显示的</p>
<slot></slot>
<slot name="two"></slot>
</div>
</template>
效果图:
3、作用域插槽
此时就映射到我们的slot-scope="scope"了
父组件接收子组件的值是用slot-scope进行接收,此时scope的名字可以为任意,它默认就是一个对象,会拿到子组件data中的所有数据
父组件:
<template>
<div class="hello">
<Children>
<!-- anyName默认可以随便起名字,它默认是一个对象,获取到的是Children组件中的data总数据,用它anyName.importData取出user数据 -->
<template slot-scope="anyName">
<p v-for="(item, index) in anyName.importData" :key="index">
{
{ item }}
</p>
</template>
</Children>
</div>
</template>
<script>
import Children from '@/components/children'
export default {
components: {
Children,
},
}
</script>
子组件:
<template>
<div>
<!-- importData待会父组件就可以用它来获得到user数据 -->
<slot :importData="user"></slot>
</div>
</template>
<script>
export default {
components: {},
name: '',
data() {
return {
user: [
{ name: '小小', age: 18 },
{ name: '大大', age: 18 },
{ name: '呼呼', age: 18 },
],
}
}
</script>
效果图:
好啦,结束,言简意赅!!