Vue的Slot高级用法

请添加图片描述

Vue的Slot高级用法

在Vue中,slot是一种与模板有关的特殊元素,它允许我们将组件模板中的一部分通用代码抽象出来,以便在外部使用。我们通常会用slot来定义组件标记的结构,以便在父组件的模板中使用。

但是,Vue的slot实际上有更多的高级用法,并且可以用于更高级的功能。在本文中,我们将探讨Vue的Slot的高级用法,并且将提供一些demo代码以帮助我们理解这些用法。

1. 名称插槽

vue的slot有两种用法:默认插槽和具名插槽。默认插槽是我们在组件中使用的最基本的插槽形式,而具名插槽则是默认插槽的变种。

1.1 默认插槽

default插槽是我们最常使用的插槽方式。它称为默认插槽,因为如果我们没有为插槽指定名称,它会默认创建一个名为"default"的插槽。默认插槽可以在组件标记的内部或外部使用,因为它们不需要任何参数或配置选项。

// Parent.vue

<template>
  <MyComponent>
    <span>内容</span>
  </MyComponent>
</template>

// MyComponent.vue

<template>
  <div>
    <slot></slot>
  </div>
</template>

在上面的示例中,我们在MyComponent组件中使用了默认插槽,如果我们没有指定插槽名称,就会自动创建"default"名称的插槽。此代码片段将从父组件的模板中提取出一个span元素,并将其放置在组件模板内部的slot元素中。

1.2 具名插槽

有时,我们需要在组件的模板中定义多个插槽,而这些插槽要具有不同的名称和不同的用途。为了避免默认插槽的混淆,Vue提供了一种称为"具名插槽"的功能。


// Parent.vue

<template>
  <MyComponent>
    <template v-slot:content>
      <span>内容</span>
    </template>
    <template v-slot:footer>
      <span>页脚</span>
    </template>
  </MyComponent>
</template>

// MyComponent.vue

<template>
  <div>
    <slot name="content"></slot>
    <slot name="footer"></slot>
  </div>
</template>

在上面的示例中,我们定义了两个具名插槽:content和footer。我们使用了"v-slot"指令来定义每个插槽的名称。在MyComponent组件中,我们使用"slot"元素并为每个插槽指定一个名称来在组件模板中定义多个插槽。这允许我们为每个插槽提供不同的内容,而不会导致混淆。

2. 作用域插槽

作用域插槽是Vue Slot的一个独特的功能。这个功能使得我们能够对子组件的插槽内容进行更多的控制,并在父组件中使用这些内容。

作用域插槽允许我们在子组件中定义一个具名插槽,并指定一些可以传递给此插槽的数据。在父级组件中,通过定义一个具名的插槽,在具有相同名称的作用域插槽中使用特定的数据,从而控制子组件行为。

作用域插槽是面向组件通信时常常用到的一个技巧。它允许子组件将其渲染输出作为插槽暴露,并允许父组件渲染具有非静态内容的模板。我们可以把这个功能放到一个简单的例子中:


// Parent.vue

<template>
  <MyComponent>
    <template v-slot:content="slotProps">
        <h1>{
   
   { slotProps.title }}</h1>
        <p>{
   
   { slotProps.body }}</p >
      </template>
   </MyComponent>
</template>

// MyComponent.vue

<template>
  <div>
    <slot name="content" :title="title" :body="body"></slot>
  </div>
</template>

<script>
export default {
  data: () => ({
    title: 'Vue的作用域插槽',
    body: '插槽可以允许你在父级组件中控制子组件的行为'
  })
}
</script>

在上面的代码中,我们在MyComponent组件中定义了一个具名插槽,并将一个对象传递给了它,使得我们可以把这些对象数据绑定到子组件的插槽中。在父级组件中,我们使用v-slot指令来指定这个作用域插槽,并使用slotProps将数据作为属性绑定到具名插槽中。

3. 动态插槽

Vue还提供了动态插槽,允许我们根据需要动态地选择子组件中的插槽。

例如,我们可以使用一个props来控制组件中显示的插槽,并根据用户的选择渲染正确的插槽。让我们见一个例子:


// Parent.vue

<template>
  <MyComponent :content-type="contentType">
    <template v-if="contentType === 'text'" v-slot:text>
      <p>这里是文本信息</p >
    </template>
    <template v-else-if="contentType === 'image'" v-slot:image>
      < img src="/assets/images/logo.png" alt="Logo">
    </template>
    <template v-else v-slot:default>
      <p>请填写内容</p >
    </template>
  </MyComponent>
</template>

// MyComponent.vue

<template>
  <div>
    <slot :name="contentType"></slot>
    <slot name="default"></slot>
  </div>
</template>

<script>
export default {
  props: {
    contentType: {
      type: String,
      default: 'default'
    }
  }
}
</script>

在上面的代码中,我们在组件模板中定义了三个具名插槽和一个默认插槽,同时使用一个名为"contentType"的prop。我们根据根据这个props来决定组件中应该渲染哪个插槽,MyComponent只渲染名为"contentType"的插槽以及默认插槽。

4. 组件插槽

Vue的插槽不仅可以用于另一个组件的视图渲染,也可以用于渲染组件本身。Vue的插槽还支持像是直接渲染组件的方式,这种方式很容易让我们实现跨组件自定义的插槽内容显示。

我们可以通过实例化要渲染的组件,然后将其作为插槽的内容来实现这一点。这种方式通常称为组件插槽。

让我们看一下组件插槽的一个简单示例:

// Parent.vue

<template>
  <MyButton>
    <template #icon>
      <i class="icon-user"></i>
    </template>
    登录
  </MyButton>
</template>

// MyButton.vue

<template>
  <button>
    <slot name="icon"></slot>
    {
   
   { $slots.default }}
  </button>
</template>

在上面的代码中,我们在父级组件的模板中定义了一个MyButton组件,并在其中使用组件插槽来指定要渲染的内容。我们将实例化一个图标组件,并将其作为 #icon 插槽的内容,同时也将字符串 “登录” 用作默认插槽的内容。

在MyButton组件中,我们使用 $slots 对象来访问插槽内容,以及在插槽上使用name属性来指定插槽名称。这样我们就可以在组件中使用这些插槽内容来定制我们的按钮。

5. Scoped Slots

作用域插槽允许我们在父级组件中向子级组件传递标记,但还有一种更高级的插槽,可以完全重用子组件中的标记。这称为 “Scoped Slots”,它是Vue插槽的一个高级用法。

Scoped Slots 允许我们在子组件中定义一个插槽,并在父组件中重复使用此插槽,同时使用子组件向父组件传递的数据。通过使用Scoped Slots,我们可以几乎完全重用子组件中的逻辑和标记,在父组件中只为需要的数据提供一个接口。

让我们看一个 Scoped Slots 的例子:

// Parent.vue

<template>
  <MyComponent>
    <template v-slot:list="slotProps">
      <ul>
        <li v-for="item in slotProps.items" :key="item.id">
          {
   
   { item.text }}
        </li>
      </ul>
    </template>
  </MyComponent>
</template>

// MyComponent.vue

<template>
  <div>
    <slot v-bind:items="items" name="list"></slot>
  </div>
</template>

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, text: 'item 1' },
        { id: 2, text: 'item 2' },
        { id: 3, text: 'item 3' }
      ]
    }
  }
}
</script>

在上面的代码中,我们在父级组件中使用Scoped Slots,用 #list 来命名一个插槽。将v-slot指令作为template元素的属性使用,这个指令允许我们为这个具名的插槽绑定数据。

在MyComponent组件中,我们使用v-bind将数据绑定到父组件允许的项目中,然后在slot元素中使用name属性,同时确保该名称与父组件中的名称对应。

在这个例子中,我们可以看到任何在父组件模板中嵌入的内容都与子组件模板相关,这允许 MyComponent 组件得以提供更灵活的标记和样式。此外,它还使得我们在子组件中可以单独处理数据,而不用担心在父组件模板中的数据额外解耦。

结论

Vue的插槽系统是Vue中非常强大且有用的一部分。除了作为最基本的使用方式之外,还有许多更高级的用法,包括具名插槽、作用域插槽、动态插槽和Scoped Slots。

通过使用这些高级用法,我们可以更好地管理 Vue 组件和应用程序中的视图和数据,并使其更易于重用和维护。如果您还没有使用到Vue的插槽高级用法,那么现在可能是时候去学习这些知识了。

以上是Vue的插槽高级用法的介绍,期望这篇文章对您有所帮助。

猜你喜欢

转载自blog.csdn.net/weixin_44599143/article/details/129595361