Vue 提供了一个非常强大的特性,叫做插槽 (slots),它允许我们定义组件模板的一部分,然后在父组件中进行填充。这为组件间的内容分发提供了极大的灵活性。在本文中,我们将通过一个简单的例子来探讨 Vue 的插槽功能。

1. 基础插槽

在 Vue 中,我们可以使用 <slot></slot> 标签在组件模板中定义一个插槽。这个插槽可以被父组件中的内容替换。

2. 具名插槽

除了默认插槽,Vue 还支持具名插槽。这允许我们在组件模板中定义多个插槽,并在父组件中为每个插槽提供不同的内容。

3. 示例讲解

考虑以下两个组件:App.vueFancyList.vue

App.vue

<script setup>
import FancyList from './FancyList.vue'
</script>

<template>
  <FancyList :api-url="url" :per-page="10">
    <template #item="{ body, username, likes }">
      <div class="item">
        <p>{{ body }}</p>
        <p class="meta">by {{ username }} | {{ likes }} likes</p>
      </div>
    </template>
  </FancyList>
</template>

<style scoped>
.meta {
  font-size: 0.8em;
  color: #42b883;
}
</style>

App.vue 中,我们导入了 FancyList 组件,并在模板中使用它。我们为 FancyList 组件提供了一个具名插槽 item,该插槽用于渲染列表中的每一项。

FancyList.vue

<script setup>
import { ref } from 'vue'

const props = defineProps(['api-url', 'per-page'])

const items = ref([])

// mock remote data fetching
setTimeout(() => {
  items.value = [
    { body: 'Scoped Slots Guide', username: 'Evan You', likes: 20 },
      { body: 'Vue Tutorial', username: 'Natalia Tepluhina', likes: 10 }
  ]
}, 1000)
</script>

<template>
  <ul>
    <li v-if="!items.length">
      Loading...
    </li>
    <li v-for="item in items">
      <slot name="item" v-bind="item"/>
    </li>
  </ul>
</template>

<style scoped>
  ul {
    list-style-type: none;
    padding: 5px;
    background: linear-gradient(315deg, #42d392 25%, #647eff);
  }
  li {
    padding: 5px 20px;
    margin: 10px;
    background: #fff;
  }
</style>

FancyList.vue 中,我们定义了一个名为 item 的具名插槽。这个插槽将被 App.vue 中的内容替换。

总结

Vue 的插槽功能为组件间的内容分发提供了极大的灵活性。通过使用默认插槽和具名插槽,我们可以轻松地在父组件中定义和覆盖子组件的内容。


希望这篇博客能帮助你更好地理解 Vue 的插槽功能!


A Student on the way to full stack of Web3.