1、插槽的使用:
~父组件index.vue:
<h3>我是父组件testSlot</h3>
<!-- 调用子组件alertBox测试插槽 -->
<alertBox></alertBox>
<alertBox>Something good will be happened.
/alertBox>
<br>
~alertBox.vue:
<template><h3>我是子组件alertBox</h3><div class="alert-box"><strong>This is a good news for this week!!!!!</strong><!-- 插槽占位,父组件调用时加入特性数据,展示特定数据 --><slot><!-- 我们使用 <slot> 作为一个占位符,父组件传递进来的内容就会渲染在这里。 --></slot></div>
</template>
效果:
2、封装button组件,通过slot插槽传入按钮名称
~父组件index.vue:
<div>##################封装button组件,通过slot插槽传入按钮名称 start #############</div><div>调用fancyButton按钮组件</div><br><FancyButton class="fancy-btn">Click me!</FancyButton><FancyButton>提交订单</FancyButton><FancyButton class="examine-btn">提交审核</FancyButton><FancyButton>{{ obj.btn_text }}</FancyButton><br><div>##################封装button组件,通过slot插槽传入按钮名称 end #############</div>
const obj = reactive({productName: 'Fancy',total: 99,sku_id: '10086',btn_text: '去支付'
})
<style lang="less" scoped>.container {h3 {text-align: center;}.fancy-btn {margin-right: 10px;}.examine-btn:hover {background-color: #A802DB;font-size: 16px;}
}</style>
~fancyBuuton.vue:
<template><button class="fancu-btn"><slot></slot></button>
</template><script setup>
import { ref, reactive } from 'vue'/*** 封装统一风格的按钮样式* 稍微有不同的可以通过 透传 attribute* “透传 attribute”指的是传递给一个组件,却没有被该组件声明为 props 或 * emits 的 attribute 或者 v-on 事件监听器。最常见的例子就是 class、style 和 id。* 详情看官网:https://cn.vuejs.org/guide/components/attrs.html*/
</script><style scoped>
.fancu-btn {background-color: #42F5E2;border-radius: 25px;font-size: 14px;cursor: pointer;outline: none;
}
</style>
效果:
3、具名插槽
~父组件index.vue:
<NamedSlots><template #header><h4>Here might be a page title</h4></template><!-- 两种写法效果相同 --><!-- <template #default><p>A paragraph for the main content.</p><p>And another one.</p></template> --><p>A paragraph for the main content.</p><p>And another one.</p><template #footer><h4>底部信息</h4><p>Here's some concat info.</p></template></NamedSlots>
~namedSlot.vue:
<template><div class="container"><header><!-- 标题内容放这里 --><slot name="header"></slot></header><main><!-- 主要内容放这里 ——不添加name,是默认插槽--><slot></slot></main><footer><!-- 底部内容放这里 --><slot name="footer"></slot></footer></div>
</template>
<script setup>
import { ref, reactive } from 'vue'
/*** 具名插槽 --- 有时在一个组件中包含多个插槽出口是很有用的。* Named slots* 这类带 name 的插槽被称为具名插槽 (named slots)。没有提供 name 的 <slot> 出口会隐式地命名为“default”。* 要为具名插槽传入内容,我们需要使用一个含 v-slot 指令的 <template> 元素,并将目标插槽的名字传给该指令:* v-slot 有对应的简写 #,因此 <template v-slot:header> 可以简写为 <template #header>。其意思就是“将这部* 分模板片段传入子组件的 header 插槽中”。*/</script>
<style scoped></style>
效果:
4、条件插槽
~父组件index.vue:
<div>##################条件插槽 start #############</div><ConditionalSlot><template #header><h4>头部数据</h4></template><template #default><p>主要内容:Here is the content.</p></template><template #footer><em>底部信息:Here is the footer!</em></template></ConditionalSlot><div>##################条件插槽 end #############</div>
conditionalSlot.vue:
<template><div class="card"><div class="card-header"><slot name="header"></slot></div><div class="card-content"><slot /></div><div class="card-footer"><slot name="footer"></slot></div></div>
</template>
<script setup>
import { ref, reactive } from 'vue'
/*** 条件插槽* 有时你需要根据插槽是否存在来渲染某些内容。* 你可以结合使用 $slots 属性与 v-if 来实现。* 在下面的示例中,我们定义了一个卡片组件,它拥有三* 个条件插槽:header、footer 和 default。 当 header、* footer 或 default 存在时,我们希望包装它们以提供额外的样式:* */</script>
<style lang="less" scoped>.card {border: 1px solid black;padding: 0;.card-header {background-color: skyblue;padding: 4px;}.card-content {background-color: pink;padding: 4px;}.card-footer {background-color: lightgray;padding: 4px;}}
</style>
效果:
5、动态插槽名:
<!-- 动态插槽名动态指令参数在 v-slot 上也是有效的,即可以定义下面这样的动态插槽名: --><!-- <base-layout><template v-slot:[dynamicSlotName]>...</template>可缩写为如下:<template #[dynamicSlotName]>...</template></base-layout> -->
6、作用域插槽:
~父组件index.vue:
<div>##################作用域插槽 start #############</div><br><!-- 通过v-slot接收传过来的数据 --><scopeSlot v-slot="props">message:{{ props.text }}count:{{ props.count }}</scopeSlot><!-- v-slot="slotProps" 可以类比这里的函数签名,和函数的参数类似,我们也可以在 v-slot 中使用解构:--><scopeSlot v-slot="{ text, count }">解构后的数据:'{{ text }}', 和 '{{ count }}''</scopeSlot><br><div>##################作用域插槽 end #############</div>
scopeSlot.vue:
<template><div class="container"><header><!-- 标题内容放这里 --><slot name="header"></slot></header><main><!-- 主要内容放这里 ——不添加name,是默认插槽--><slot></slot></main><footer><!-- 底部内容放这里 --><slot name="footer"></slot></footer></div>
</template>
<script setup>
import { ref, reactive } from 'vue'
/*** 具名插槽 --- 有时在一个组件中包含多个插槽出口是很有用的。* Named slots* 这类带 name 的插槽被称为具名插槽 (named slots)。没有提供 name 的 <slot> 出口会隐式地命名为“default”。* 要为具名插槽传入内容,我们需要使用一个含 v-slot 指令的 <template> 元素,并将目标插槽的名字传给该指令:* v-slot 有对应的简写 #,因此 <template v-slot:header> 可以简写为 <template #header>。其意思就是“将这部* 分模板片段传入子组件的 header 插槽中”。*/</script>
<style scoped></style>
效果:
7、具名作用域插槽
~父组件index.vue:
<div>##################具名作用域插槽 start #############</div><!-- 解构或者通过变量接收参数都可以 --><NamedScopeSlot v-slot:header="{msg}">具名作用域插槽数据:{{ msg }}</NamedScopeSlot><!-- 等同于下面 --><NamedScopeSlot #header="{msg}">具名作用域插槽数据:{{ msg }}</NamedScopeSlot><!-- 注意插槽上的 name 是一个 Vue 特别保留的 attribute,不会作为 props 传递给插槽。因此最终 headerProps 的结果是 { message: 'hello' }。 --><NamedScopeSlot #header="{name, msg}">具名作用域插槽数据:{{ name }} {{ msg }}</NamedScopeSlot><div>##################具名作用域插槽 end #############</div>
namedScopeSlot.vue:
<template><div><!-- 具名作用域插槽 --><slot name="header" msg="Hello, Friday"></slot></div>
</template>
<script setup>
import { ref, reactive } from 'vue'</script>
<style scoped></style>
效果:
以上就是插槽的使用,源码里面有注释说明。