Vue 插槽(Slot)用法详解

发布于:2025-06-10 ⋅ 阅读:(18) ⋅ 点赞:(0)

插槽(Slot)是Vue中一种强大的内容分发机制,它允许你在组件中定义可替换的内容区域,为组件提供了更高的灵活性和可复用性。本文将全面介绍Vue插槽的各种用法。

1. 基本插槽

基本插槽是最简单的插槽形式,它允许父组件向子组件插入内容。

子组件定义插槽:

<!-- ChildComponent.vue -->
<template>
  <div class="child">
    <h2>子组件标题</h2>
    <slot></slot>  <!-- 插槽位置 -->
    <p>子组件底部内容</p>
  </div>
</template>

父组件使用:

<template>
  <ChildComponent>
    <p>这是插入到子组件中的内容</p>
  </ChildComponent>
</template>

2. 后备内容(默认内容)

插槽可以设置默认内容,当父组件没有提供内容时显示。

<!-- ChildComponent.vue -->
<template>
  <button type="submit">
    <slot>提交</slot>  <!-- 默认显示"提交" -->
  </button>
</template>

3. 具名插槽

当一个组件需要多个插槽时,可以使用具名插槽。

子组件定义:

<!-- BaseLayout.vue -->
<template>
  <div class="container">
    <header>
      <slot name="header"></slot>
    </header>
    <main>
      <slot></slot>  <!-- 默认插槽,没有name属性 -->
    </main>
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

父组件使用:

<template>
  <BaseLayout>
    <template v-slot:header>
      <h1>这里是页眉</h1>
    </template>
    
    <p>这里是主内容,会放入默认插槽</p>
    
    <template v-slot:footer>
      <p>这里是页脚</p>
    </template>
  </BaseLayout>
</template>

4. 作用域插槽

作用域插槽允许子组件向插槽传递数据,父组件可以决定如何渲染这些数据。

子组件定义:

<!-- TodoList.vue -->
<template>
  <ul>
    <li v-for="(item, index) in items" :key="index">
      <slot :item="item" :index="index"></slot>
    </li>
  </ul>
</template>

<script>
export default {
  data() {
    return {
      items: ['吃饭', '睡觉', '写代码']
    }
  }
}
</script>

父组件使用:

<template>
  <TodoList>
    <template v-slot:default="slotProps">
      <span v-if="slotProps.index % 2 === 0">✓</span>
      {{ slotProps.item }}
    </template>
  </TodoList>
</template>

5. 解构插槽Prop

在作用域插槽中,可以使用ES6解构语法简化代码:

<template>
  <TodoList>
    <template v-slot:default="{ item, index }">
      <span v-if="index % 2 === 0">✓</span>
      {{ item }}
    </template>
  </TodoList>
</template>

6. 动态插槽名

插槽名可以是动态的:

<template>
  <base-layout>
    <template v-slot:[dynamicSlotName]>
      ...
    </template>
  </base-layout>
</template>

<script>
export default {
  data() {
    return {
      dynamicSlotName: 'header'
    }
  }
}
</script>

7. 缩写语法

Vue提供了插槽的缩写语法:

  • v-slot:header 可以简写为 #header

  • 默认插槽 v-slot:default 可以简写为 v-slot 或 #default

<template>
  <BaseLayout>
    <template #header>
      <h1>页眉</h1>
    </template>
    
    <template #default>
      <p>主内容</p>
    </template>
    
    <template #footer>
      <p>页脚</p>
    </template>
  </BaseLayout>
</template>

8. 高级用法:插槽函数

插槽可以像函数一样使用,实现更灵活的内容分发:

子组件:

<template>
  <div>
    <slot :user="user" :isLoggedIn="isLoggedIn"></slot>
  </div>
</template>

<script>
export default {
  data() {
    return {
      user: { name: '张三', age: 30 },
      isLoggedIn: true
    }
  }
}
</script>

父组件:

<template>
  <UserComponent>
    <template v-slot="{ user, isLoggedIn }">
      <div v-if="isLoggedIn">
        欢迎, {{ user.name }}! 您已经{{ user.age }}岁了。
      </div>
      <div v-else>
        请登录
      </div>
    </template>
  </UserComponent>
</template>

总结

Vue插槽提供了强大的内容分发机制,通过基本插槽、具名插槽、作用域插槽等特性,可以创建高度可复用和灵活的组件。掌握插槽的使用可以显著提升Vue组件的开发效率和可维护性。

在实际开发中,插槽常用于构建布局组件、高阶组件(HOC)、列表渲染等场景,是Vue组件化开发的重要工具之一。