【vue3】08-vue的组件化开发-插槽(Slots)的完全指南

Vue插槽(Slots)的完全指南

  • 插槽的作用
  • 插槽的基本使用
  • 具名插槽
  • 作用域插槽(难点)

插槽的作用

在开发中,我们会经常封装一个个可复用的组件:

  • 前面我们会通过props传递给组件一些数据,让组件来进行展示;
  • 但是为了让这个组件具备更强的通用性,我们不能将组件中的内容限制为固定的div、span等等这些元素;
  • 比如某种情况下我们使用组件,希望组件显示的是一个按钮,某种情况下我们使用组件希望显示的是一张图片;
  • 我们应该让使用者可以决定某一块区域到底存放什么内容和元素;

假如我们定制一个通用的导航组件–NavBar:

  • 这个组件分成三块区域:左边-中间-右边,每块区域的内容是不固定;
  • 左边区域可能显示一个菜单图标,也可能显示一个返回按钮,可能什么都不显示;
  • 中间区域可能显示一个搜索框,也可能是一个列表,也可能是一个标题,等等;
  • 右边可能是一个文字,也可能是一个图标,也可能什么都不显示;

【vue3】08-vue的组件化开发-插槽(Slots)的完全指南_第1张图片

这个时候我们就可以来定义插槽slot:

  • 插槽的使用过程其实是抽取共性、预留不同;
  • 我们会将共同的元素、内容依然在组件内进行封装;
  • 同时会将不同的元素使用slot作为占位,让外部决定到底显示什么样的元素;

如何使用slot呢?

  • Vue中将元素作为承载分发内容的出口;
  • 在封装组件中,使用特殊的元素就可以为封装组件开启一个插槽;
  • 该插槽插入什么内容取决于父组件如何使用;

【vue3】08-vue的组件化开发-插槽(Slots)的完全指南_第2张图片


插槽的基本使用

基本插槽,也称为匿名插槽,是使用时不需要为插槽指定名称的插槽。使用基本插槽的方式非常简单,可以直接在组件内部使用来定义一个匿名插槽:

<template>
    <h2>{{ title }}h2>
    <div class="content">
        <slot>我是插槽默认内容slot>
    div>
template>
      
      
<script>
export default {
    props: {
        title: {
            type: String,
            default: "我是标题"
        }
    }
}
script>

在上面的例子中,我们在子组件ShowMessage中定义了一个匿名插槽。当父组件使用时,插槽将会被替换为组件的内容。

<template>
    <div id="app">
        <show-message title="我是标题">show-message>
        <show-message title="我是标题2">
            <button>按钮button>
        show-message>
        <show-message title="我是标题3">
            <a href="#">我是超链接a>
        show-message>

        <show-message title="我是标题4">
            <img src="@/IMG/noteBorad.png" alt="">
        show-message>

    div>
template>
      
      
<script>
import ShowMessage from "./components/ShowMessage.vue";

export default {
    components: {
        ShowMessage
    }
}
script>

在这个例子中,使用子组件时按钮,超链接,图片将分别作为插槽的内容被嵌入到组件中,效果如下:

【vue3】08-vue的组件化开发-插槽(Slots)的完全指南_第3张图片

但如果同时有多个插槽,如左中右区域都留有插槽,我们该如何分别将内容插入到对应的插槽中呢,这时候就需要使用具名插槽。


具名插槽

释义:具名插槽是指为插槽赋予名称,以便使用者可以向指定的插槽中插入内容

使用具名插槽的方式是元素添加一个name属性,如下所示:

<template>
  <div class="nav-bar">
    
    <div class="left">
      <slot name="left">leftcontentslot>
    div>
    <div class="center">
      <slot name="center">centercontentslot>
    div>
    <div class="right">
      <slot name="right">rightcontentslot>
    div>
  div>
template>

在上面的例子中,我们定义了一个NavBar组件并在其中定义了名为“left”,"center"和"right"的三个具名插槽。并分别给了默认内容leftcontent,centercontent,rightcontent

当在父组件使用时,可以使用