Vue3插槽学习

插槽

插槽的分类如下。 1. 默认插槽; 2. 默认作用域插槽; 3. 具名插槽; 4. 具名作用插槽;

普通插槽是一种用于将内容插入到组件中指定位置的机制,它允许父组件向子组件传递 DOM 元素或组件实例作为子组件的一部分进行渲染。普通插槽可以在子组件中使用 <slot> ​元素来定义,使用时可以在父组件中将内容插入到指定的插槽位置。下面是一个普通插槽的代码示例:

<!-- 子组件 -->
<template>
  <div>
    <h2>子组件</h2>
    <slot></slot>
  </div>
</template>

<!-- 父组件 -->
<template>
  <div>
    <h1>父组件</h1>
    <child-component>
      <p>这是插入到子组件中的内容</p>
    </child-component>
  </div>
</template>

在上面的代码中,子组件 <child-component> ​中使用了一个普通插槽,通过 <slot> ​元素来定义。在父组件中,将要插入到子组件中的内容包裹在 <child-component> ​标签中即可。

作用域插槽是一种允许子组件向父组件传递数据的机制,它允许父组件将子组件的数据作为参数传递给插槽内容,从而实现更灵活的组件复用。作用域插槽可以在子组件中使用 <slot> ​元素,并通过 v-bind ​指令将数据传递给插槽内容。下面是一个作用域插槽的代码示例:

<!-- 子组件 -->
<template>
  <div>
    <h2>子组件</h2>
    <slot :data="childData"></slot>
  </div>
</template>

<!-- 父组件 -->
<template>
  <div>
    <h1>父组件</h1>
    <child-component>
      <template #default="{ data }">
        <p>这是插入到子组件中的内容,子组件传递的数据是:{{ data }}</p>
      </template>
    </child-component>
  </div>
</template>

在上面的代码中,子组件 <child-component> ​中使用了一个作用域插槽,通过 <slot> ​元素和 v-bind ​指令来定义。在父组件中,使用 <template> ​标签来定义插槽内容,并通过 #default ​指令来指定插槽名称。在插槽内容中,使用 data ​变量来接收子组件传递的数据,并渲染到页面中。

1、默认插槽

插槽图示

<!-- 子组件Test.vue -->
<template>
  <div>
    <h2>子组件</h2>
    <slot></slot>
  </div>
</template>

<!-- 父组件App.vue -->
<template>
  <div>
    <h1>父组件</h1>
    <child-component>     //<Test>
      <p>这是插入到子组件中的内容</p>
    </child-component>    //</Test>
  </div>
</template>

插槽内容可以是任意合法的模板内容,不局限于文本。例如我们可以传入多个元素,甚至是组件:

<FancyButton>
  <span style="color:red">Click me!</span>
  <AwesomeIcon name="plus" />
</FancyButton>

在父组件没有提供任何插槽内容时在 <button>​ 内渲染“Submit”,只需要将“Submit”写在 <slot>​ 标签之间来作为默认内容:

<button type="submit">
  <slot>
    Submit <!-- 默认内容 -->
  </slot>
</button>

在父组件中使用 <SubmitButton>​ 且没有提供任何插槽内容时,会以默认内容渲染,有插槽内容时,被显式提供的内容会代替默认内容。

2、默认作用域插槽

​[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gy6aUG5z-1686584687161)(null)]​

<MyComponent v-slot="slotProps">
  {{ slotProps.text }} {{ slotProps.count }}
</MyComponent>

v-slot="slotProps"​ 可以类比这里的函数签名,和函数的参数类似,可以在 v-slot​ 中使用解构:

<MyComponent v-slot="{ text, count }">
  {{ text }} {{ count }}
</MyComponent>

3、具名插槽

具名插槽图示

<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>

这类带 name​ 的插槽被称为具名插槽 (named slots)。没有提供 name​ 的 <slot>​ 出口会隐式地命名为“default”。

<BaseLayout>
  <template v-slot:header>  //可写为<template #header>
    <!-- header 插槽的内容放这里 -->
  </template>

  <template #default>    //可以不写。当一个组件同时接收默认插槽和具名插槽时,所有位于顶级的非 <template> 节点都被隐式地视为默认插槽的内容。
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>	//可以不写

  <template #footer>
    <p>Here's some contact info</p>
  </template>
</BaseLayout>

v-slot​ 有对应的简写 #​,因此 <template v-slot:header>​ 可以简写为 <template #header>​。其意思就是“将这部分模板片段传入子组件的 header 插槽中”。

4、具名作用域插槽

<MyComponent>
  <template #header="headerProps">
    {{ headerProps }}
  </template>

  <template #default="defaultProps">
    {{ defaultProps }}
  </template>

  <template #footer="footerProps">
    {{ footerProps }}
  </template>
</MyComponent>

向具名插槽中传入 props:

<slot name="header" message="hello"></slot>

注意插槽上的 name​ 是一个 Vue 特别保留的 attribute,不会作为 props 传递给插槽。因此最终 headerProps​ 的结果是 { message: 'hello' }​。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值