vue3:插槽、具名插槽、条件插槽、作用域插槽、具名作用域插槽 一次性搞清楚 --- 通俗易懂
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
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>
效果:
以上就是插槽的使用,源码里面有注释说明。
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献13条内容
所有评论(0)