vue中的插槽
阅读数:111 评论数:0
跳转到新版页面分类
html/css/js
正文
一、概念
vue插槽的作用是让父组件可以向子组件指定位置插入html结构,在要接收数据的组件页面通过<slot>标签来表示,通过此标签来起到占位符的作用,插槽的本质是传递函数。
1、插槽版本变化
从2.6.0版本,为具名插槽和作用域插槽引入了一个新的语法,即v-slot指令,用以取代slot和slot-scope。
2、具名插槽的缩写
跟v-on(@) v-bind(:)一样,v-slot也有缩写,即把参数之前的所有内容(v-slot:)替换为字符#,例如v-slot:header可以重写成#header
<!-- ParentComponent.vue -->
<template>
<ChildComponent>
<template #header>
<h1>这是头部</h1>
</template>
<p>这是主体内容</p>
<template #footer>
<p>这是底部</p>
</template>
</ChildComponent>
</template>
二、单个插槽
单个插槽是vue的官方的叫法,但是其实也可以叫它默认插槽,或者与具名插槽相对,称为匿名插槽,因为它不用于设置name属性。
单个插槽可以放置在组件的任意位置,但是就像它的名字一样,一个组件中只能有一个该类插槽。相对应的,具名插槽就可以有很多个,只要名字(name属性)不同就可以了。
<template>
<div class="father">
<h3>这里是父组件</h3>
<child>
<div class="tmpl">
<span>菜单1</span>
<span>菜单2</span>
<span>菜单3</span>
<span>菜单4</span>
<span>菜单5</span>
<span>菜单6</span>
</div>
</child>
</div>
</template>
<template>
<div class="child">
<h3>这里是子组件</h3>
<slot></slot>
</div>
</template>
三、具名插槽
插槽加了name属性,就变成了具名插槽。具名插槽可以在一个组件中出现N次。
<!-- ChildComponent.vue -->
<template>
<div>
<slot name="header">默认头部内容</slot>
<slot>默认主体内容</slot>
<slot name="footer">默认底部内容</slot>
</div>
</template>
<!-- ParentComponent.vue -->
<template>
<ChildComponent>
<template v-slot:header>
<h1>这是头部</h1>
</template>
<p>这是主体内容</p>
<template v-slot:footer>
<p>这是底部</p>
</template>
</ChildComponent>
</template>
在这个例子中,<template v-slot:header>
定义了 header
插槽的内容,<template v-slot:footer>
定义了 footer
插槽的内容。未命名的 <p>这是主体内容</p>
将填充默认插槽。
四、作用域插槽(带数据的插槽)
1、子组件
在子组件中,你定义一个插槽并决定哪些数据要暴露给父组件。这是通过在 <slot>
标签上添加一个特殊的属性完成的,通常这个属性是一个对象,包含了你想要传递的所有数据。
<!-- ChildComponent.vue -->
<template>
<div>
<slot name="default" :item="itemData"></slot>
</div>
</template>
<script>
export default {
props: ['itemData'],
};
</script>
在这个例子中,ChildComponent
接收一个 itemData
属性,并将其作为一个名为 default
的插槽的数据传递。
2、父组件
在父组件中,你使用这个插槽,并通过一个特殊的 v-slot
指令(或其缩写 #
)来接收子组件传递的数据。
<!-- ParentComponent.vue -->
<template>
<ChildComponent :item-data="{ name: 'Vue 3' }">
<template v-slot:default="slotProps">
<div>{{ slotProps.item.name }}</div>
</template>
</ChildComponent>
</template>
在这个例子中,ParentComponent
通过 v-slot:default="slotProps"
接收了 ChildComponent
传递的 itemData
。在这个模板块中,slotProps
是一个包含所有传递给插槽的数据的对象,这里是 itemData
对象。
3、解构
在实际使用时,你通常会对 v-slot
传递的对象进行解构,以直接使用其中的属性,这使得模板更加简洁。
<!-- ParentComponent.vue -->
<template>
<ChildComponent :item-data="{ name: 'Vue 3' }">
<template #default="{ item }">
<div>{{ item.name }}</div>
</template>
</ChildComponent>
</template>
在这个例子中,#default="{ item }"
是 v-slot:default="slotProps"
的缩写形式,并且我们直接解构了 item
对象,从而可以直接使用 item.name
。
4、动态插槽名
有时候,你可能还想根据一些条件动态决定使用哪个插槽。Vue 3 允许你使用计算属性或方法来动态定义插槽名。
<!-- ParentComponent.vue -->
<template>
<ChildComponent :item-data="{ name: 'Vue 3' }">
<template v-slot:[dynamicSlotName]="slotProps">
<div>{{ slotProps.item.name }}</div>
</template>
</ChildComponent>
</template>
<script>
export default {
computed: {
dynamicSlotName() {
// 可以根据一些条件来返回不同的插槽名
return 'default';
},
},
};
</script>
在这个例子中,v-slot:[dynamicSlotName]
使用方括号语法来绑定一个动态的插槽名,这个名字是通过 dynamicSlotName
计算属性得到的。