Vue中如何使用插槽(slot)?

插槽是Vue组件化中一个非常强大的内容分发API。它允许父组件向子组件传递模板片段(不仅仅是数据),让子组件能够灵活地渲染这些内容,从而实现高度的可定制性和复用性。

默认插槽

最简单的是默认插槽。子组件使用<slot>标签定义一个占位符,父组件传递给子组件开始和结束标签之间的任何内容,都会渲染在这个位置。

<!-- 子组件 BaseButton.vue -->
<template>
  <button class="btn">
    <slot></slot> <!-- 内容将在这里渲染 -->
  </button>
</template>

<!-- 父组件 -->
<BaseButton>点击我</BaseButton>
<BaseButton>
  <span style="color: red;">带样式的文本</span>
</BaseButton>

如果子组件的<slot>内部有内容,它将作为后备内容,当父组件没有提供内容时显示。

<slot>默认提交</slot> <!-- 父组件不传内容时,显示“默认提交” -->

具名插槽

当需要多个插槽时,可以使用具名插槽。子组件通过<slot name="xxx">定义不同名称的插槽,父组件则使用v-slot:xxx#xxx指令将内容分发到对应的位置。

<!-- 子组件 Layout.vue -->
<template>
  <div class="container">
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot> <!-- 匿名默认插槽 -->
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

<!-- 父组件 -->
<Layout>
  <template v-slot:header>
    <h1>这是标题</h1>
  </template>

  <p>这是主内容,会放入默认插槽。</p>

  <template #footer> <!-- # 是 v-slot 的简写 -->
    <p>这是页脚</p>
  </template>
</Layout>

作用域插槽

作用域插槽是最强大的特性。它允许子组件在插槽内向父组件传递数据,使父组件可以控制如何渲染这部分内容,但数据来源于子组件。

<!-- 子组件 TodoList.vue -->
<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      <!-- 将 item 数据作为 slot 的一个属性传递出去 -->
      <slot :item="item" :index="index">
        后备: {{ item.name }}
      </slot>
    </li>
  </ul>
</template>
<script>
export default {
  props: ['items']
}
</script>

<!-- 父组件 -->
<TodoList :items="todoList">
  <template v-slot:default="slotProps">
    <!-- slotProps 接收子组件传递的所有属性对象 -->
    <span :class="{ done: slotProps.item.completed }">
      {{ slotProps.index }} - {{ slotProps.item.name }}
    </span>
  </template>
</TodoList>

可以使用ES6解构让模板更简洁:v-slot="{ item, index }"

插槽机制让Vue组件超越了单纯的数据输入输出模型,实现了更高级的布局和内容抽象。它是构建灵活、可复用UI库(如卡片、模态框、布局组件)的基石。合理运用插槽,能极大地提升组件的通用性和表达力。

© 版权声明
THE END
喜欢就支持一下吧
点赞6 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容