12. 插槽
于2022-10-12 16:08:13发布
88
默认插槽
父组件
<template>
<div id="app">
<MyBanner>
<div>头部</div>
</MyBanner>
</div>
</template>
子组件
<template>
<div>
<slot>header</slot>
</div>
</template>
父组件的<div>头部</div> 将会替换子组件的<slot>header</slot>
tips:子组件的<slot>header</slot>,如果父组件没有传递数据过来,则默认显示<slot>header</slot>。比如这样:
<template>
<div id="app">
<MyBanner>
<!--这里什么都没有-->
</MyBanner>
</div>
</template>
<slot>header</slot>将会被替换成<div>header</div>
具名插槽
父组件
<template>
<div id="app">
<MyBanner>
<div slot="footer">底部</div>
</MyBanner>
</div>
</template>
子组件
<template>
<div>
<slot name="footer"></slot>
</div>
</template>
父组件的<div slot="footer">底部</div>将会替换子组件的<slot name="footer"></slot>
在日常的开发中,有时候我们需要传递的数据不是dom元素,而是一个template标签。传递template标签有以下2种传递方式 :
传递方式1(父组件)
<template>
<div id="app">
<MyBanner>
<template slot="footer"> <!--还是用slot起名字-->
<div>底部</div>
</template>
</MyBanner>
</div>
</template>
传递方式2 (父组件)
<template>
<div id="app">
<MyBanner>
<template v-slot:footer><!--用v-slot起名字-->
<div>底部</div>
</template>
</MyBanner>
</div>
</template>
子组件
<template>
<div>
<slot name="footer"></slot>
</div>
</template>
大部分情况下,你应该用第二种方式。需要注意的是,v-slot:footer是可以简写的,如:
<template>
<div id="app">
<MyBanner>
<template #footer> <!--把v-slot:改成#-->
<div>底部</div>
</template>
</MyBanner>
</div>
</template>
作用域插槽
此插槽用于子组件向父组件传递数据,刚好和上面介绍的插槽相反。
例子
子组件
<template>
<div>
<slot :navList="navList"></slot>
</div>
</template>
<script>
export default {
data() {
return {
navList: [{
name: 'baidu',
url: 'https://www.baidu.com'
},{
name: 'google',
url: 'https://www.google.com'
}]
}
}
}
</script>
父组件
<template>
<div id="app">
<MyBanner>
<template v-slot="myBannerProps"> <!--v-slot除了可以用来起名字外,还可以用来接收子组件传递过来的数据。需要注意的是接收数据是等号,起名字是冒号-->
<ul>
<li v-for="(item, key) in myBannerProps.navList" :key="key">
{{ item.name }} --- {{ item.url }}
</li>
</ul>
</template>
</MyBanner>
</div>
</template>
<script>
import MyBanner from './components/MyBanner.vue'
export default {
components: {
MyBanner
}
}
</script>
tips:如果子组件的插槽是具名插槽,则父组件可以这样写 :
子组件
<template>
<div>
<slot name="content" :navList="navList"></slot> <!--具名插槽-->
</div>
</template>
<script>
export default {
data() {
return {
navList: [{
name: 'baidu',
url: 'https://www.baidu.com'
},{
name: 'google',
url: 'https://www.google.com'
}]
}
}
}
</script>
父组件
<template>
<div id="app">
<MyBanner>
<template #content="myBannerProps"> <!--#content代表替换子组件name为content的插槽,="myBannerProps" 代表接收子组件发送过来的数据-->
<ul>
<li v-for="(item, key) in myBannerProps.navList" :key="key">
{{ item.name }} --- {{ item.url }}
</li>
</ul>
</template>
</MyBanner>
</div>
</template>
<script>
import MyBanner from './components/MyBanner.vue'
export default {
components: {
MyBanner
}
}
</script>