Vue中插槽slot的用法详解

 更新时间:2024年11月26日 09:04:16   作者:景天科技苑  
插槽(Slot)是Vue.js中一个非常重要的概念,它极大地提高了组件的复用性和灵活性,通过插槽,我们可以自定义组件的内容,使其能够适应不同的场景,本文将结合实际案例,详细介绍Vue中插槽的基本用法、类型以及高级技巧,需要的朋友可以参考下

Vue插槽

插槽(Slot)是Vue.js中一个非常重要的概念,它极大地提高了组件的复用性和灵活性。通过插槽,我们可以自定义组件的内容,使其能够适应不同的场景。本文将结合实际案例,详细介绍Vue中插槽的基本用法、类型以及高级技巧。

一、插槽的基本概念

在Vue中,子组件的模板可以定义多个插槽(包括默认插槽和具名插槽等),而父组件在引用子组件时,可以根据需要有选择性地为这些插槽插入内容。如果父组件没有为某个插槽提供内容,那么子组件的模板中该插槽的位置将显示为该插槽的默认内容(如果有的话),或者简单地留空。

二、默认插槽

默认插槽是插槽家族中最简单的使用方式,它没有指定名称,用于接收父组件传递的未明确指定插槽名称的内容。

1. 基本语法

在子组件中使用<slot></slot>定义默认插槽的位置,父组件中直接放在子组件标签内的内容会被渲染到该位置。

2. 代码示例

子组件(DefaultSlotChild.vue):

<template>
  <div class="child">
    <h2>我是子组件的标题</h2>
    <!-- 默认插槽 -->
    <slot></slot>
  </div>
</template>

父组件:

<template>
  <div>
    <DefaultSlotChild>
      <!-- 这里的内容会被渲染到子组件的默认插槽中 -->
      <p>这是来自父组件的默认插槽内容1</p>
      <p>这是来自父组件的默认插槽内容2</p>
    </DefaultSlotChild>
  </div>
</template>

<script>
import DefaultSlotChild from './DefaultSlotChild.vue';

export default {
  components: {
    DefaultSlotChild
  }
}
</script>

在这个例子中,父组件传递了两个段落标签到子组件的默认插槽中,这两个段落标签会被渲染到子组件模板的<slot></slot>位置。

3. 后备内容(默认值)

如果父组件没有为默认插槽提供内容,子组件的模板中该插槽的位置可以显示后备内容(默认内容)。

<template>
  <div class="child">
    <h2>我是子组件的标题</h2>
    <!-- 默认插槽,带有后备内容 -->
    <slot>这是默认插槽的后备内容</slot>
  </div>
</template>

当父组件没有为默认插槽提供内容时,后备内容“这是默认插槽的后备内容”会被渲染出来。

三、具名插槽

具名插槽用于接收父组件中明确指定插槽名称的内容。它允许一个组件内有多个插槽,每个插槽可以有不同的内容。

1. 基本语法

在子组件中使用<slot name="插槽名称"></slot>定义具名插槽,父组件中通过<template v-slot:插槽名称>或简写为<template #插槽名称>来指定内容应该插入哪个具名插槽。

2. 代码示例

子组件(NamedSlotChild.vue):

<template>
  <div class="child">
    <header>
      <!-- 具名插槽: header -->
      <slot name="header"></slot>
    </header>
    <main>
      <!-- 默认插槽 -->
      <slot></slot>
    </main>
    <footer>
      <!-- 具名插槽: footer -->
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

父组件:

<template>
  <NamedSlotChild>
    <template v-slot:header>
      <!-- 这里的内容会被渲染到子组件的header插槽中 -->
      <h1>这是标题</h1>
    </template>
    <p>这是默认插槽的内容。</p>
    <template v-slot:footer>
      <!-- 这里的内容会被渲染到子组件的footer插槽中 -->
      <p>这是页脚</p>
    </template>
  </NamedSlotChild>
</template>

<script>
import NamedSlotChild from './NamedSlotChild.vue';

export default {
  components: {
    NamedSlotChild
  }
}
</script>

在这个例子中,父组件为子组件的header插槽和footer插槽分别提供了内容,而默认插槽则接收了一个段落标签。

3. v-slot的简写

v-slot的写法较长,Vue提供了一个简写方式,即将v-slot:简写为#

<template #header>
  <!-- 这里的内容会被渲染到子组件的header插槽中 -->
  <h1>这是标题</h1>
</template>

四、作用域插槽

作用域插槽是一种特殊的插槽,它允许子组件将数据暴露给父组件的插槽内容。这样,父组件可以使用子组件传递的数据来定制插槽的内容。

1. 基本语法

在子组件中,通过<slot :数据名="数据值"></slot>将数据传递给插槽。在父组件中,通过<template v-slot:插槽名称="slotProps">接收数据,并使用slotProps来访问传递过来的数据。

2. 代码示例

子组件(ScopedSlotChild.vue):

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

<script>
export default {
  data() {
    return {
      items: [
        { id: 1, text: '苹果' },
        { id: 2, text: '香蕉' },
        { id: 3, text: '橙子' }
      ]
    }
  }
}
</script>

父组件:

<template>
  <ScopedSlotChild>
    <template v-slot:item="slotProps">
      <!-- 使用slotProps访问子组件传递的数据 -->
      <strong>{{ slotProps.item.text }}</strong>
    </template>
  </ScopedSlotChild>
</template>

<script>
import ScopedSlotChild from './ScopedSlotChild.vue';

export default {
  components: {
    ScopedSlotChild
  }
}
</script>

在这个例子中,子组件将items数组中的每个元素通过作用域插槽传递给父组件,父组件使用slotProps访问传递过来的数据,并将其渲染为粗体文本。

3. 动态插槽名

插槽的名称也可以是动态的,根据组件的状态或其他条件来决定使用哪个插槽。在父组件中,通过:slot="动态名称"来绑定插槽的名称,其中动态名称可以是一个计算属性、方法返回值或数据属性。

五、综合案例:封装表格组件

在实际项目中,封装表格组件是一个常见的需求。通过插槽,我们可以自定义表格的每一列,使其能够适应不同的数据类型和展示方式。

代码准备

根组件(APP.vue):

<template>
  <div>
    <MyTable :data="list1">
      <!-- 使用插槽 -->
      <template #default="obj">
        <button @click="del(obj.row.id)">删除</button>
      </template>
    </MyTable>
    <MyTable :data="list2">
      <template v-slot:default="{ row }">
        <button @click="show(row)">查看</button>
      </template>
    </MyTable>
  </div>
</template>

<script>
import MyTable from './components/MyTable.vue';

export default {
  data() {
    return {
      list1: [
        { id: 1, name: '赵天明', age: 25 },
        { id: 2, name: '李翔飞', age: 22 },
        { id: 3, name: '吴国基', age: 24 }
      ],
      list2: [
        { id: 4, name: '王小明', age: 26 },
        { id: 5, name: '张小丽', age: 23 },
        { id: 6, name: '李大力', age: 27 }
      ]
    };
  },
  methods: {
    del(id) {
      this.list1 = this.list1.filter(item => item.id !== id);
    },
    show(row) {
      alert(`姓名:${row.name}; 年龄:${row.age}`);
    }
  },
  components: {
    MyTable
  }
}
</script>

子组件(MyTable.vue)

<template>
  <div class="my-table">
    <table>
      <thead>
        <tr>
          <th>ID</th>
          <th>姓名</th>
          <th>年龄</th>
          <th>操作</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="row in data" :key="row.id">
          <td>{{ row.id }}</td>
          <td>{{ row.name }}</td>
          <td>{{ row.age }}</td>
          <td>
            <!-- 使用插槽来渲染操作列 -->
            <slot :row="row"></slot>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  name: 'MyTable',
  props: {
    data: {
      type: Array,
      required: true
    }
  }
}
</script>

<style scoped>
.my-table {
  width: 100%;
  border-collapse: collapse;
}

.my-table th, .my-table td {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
}

.my-table th {
  background-color: #f2f2f2;
}
</style>

综合案例解析

在这个综合案例中,我们封装了一个简单的表格组件MyTable,它接收一个data属性,该属性是一个对象数组,每个对象代表表格中的一行数据。MyTable组件内部使用v-for指令遍历data数组,并为每一行数据生成一个表格行(<tr>)。

在表格的最后一列(操作列),我们使用了插槽(<slot :row="row"></slot>),这样父组件就可以自定义这一列的内容。通过v-slot:default="{ row }"语法,父组件可以接收到子组件传递的每一行数据,并据此渲染相应的操作按钮或链接。

父组件中的使用

在父组件中,我们创建了两个数据列表list1list2,并分别将它们传递给两个MyTable组件实例。对于第一个MyTable组件实例,我们使用了一个带命名的插槽(虽然这里使用的是默认插槽,但命名插槽的语法类似),并通过@click事件监听器绑定了删除操作。对于第二个MyTable组件实例,我们使用了简写的插槽语法,并通过show方法实现了查看操作。

插槽的作用

在这个案例中,插槽的作用主要体现在以下几个方面:

  1. 提高组件的复用性:通过插槽,我们可以将表格的操作列留给父组件自定义,这样MyTable组件就可以适用于不同的场景,而无需修改组件本身的代码。

  2. 实现数据的灵活展示:父组件可以根据需要传递不同的数据给子组件,并通过插槽展示这些数据。在这个案例中,父组件通过插槽传递了删除和查看两个操作按钮,而这两个操作的具体实现则是由父组件控制的。

  3. 保持组件的简洁性:将复杂的展示逻辑放在父组件中处理,可以使子组件保持简洁和专注。在这个案例中,MyTable组件只负责渲染表格的基本结构,而具体的操作逻辑则留给父组件实现。

六、总结

插槽是Vue中一个非常强大的功能,它允许我们在子组件中定义插槽位置,并在父组件中填充这些内容。通过插槽,我们可以实现组件的高度自定义和复用性。在本文中,我们详细介绍了默认插槽、具名插槽和作用域插槽的基本用法,并通过一个综合案例展示了如何在实际项目中应用这些插槽类型来封装表格组件。希望这些内容能帮助你更好地理解和使用Vue中的插槽功能。

以上就是Vue中插槽slot的用法详解的详细内容,更多关于Vue插槽slot用法的资料请关注脚本之家其它相关文章!

相关文章

  • Vue自定义模态对话框弹窗

    Vue自定义模态对话框弹窗

    这篇文章主要为大家详细介绍了Vue自定义模态对话框弹窗,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • vue项目中页面跳转传参的方法总结

    vue项目中页面跳转传参的方法总结

    在Vue项目中,你可以使用路由(vue-router)来实现页面跳转并传递参数,这篇文章主要为大家整理了一些常用的方法,感兴趣的小伙伴可以学习一下
    2023-11-11
  • 详解vue-template-admin三级路由无法缓存的解决方案

    详解vue-template-admin三级路由无法缓存的解决方案

    这篇文章主要介绍了vue-template-admin三级路由无法缓存的解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-03-03
  • Vue 拦截器对token过期处理方法

    Vue 拦截器对token过期处理方法

    下面小编就为大家分享一篇Vue 拦截器对token过期处理方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Vue实现飞机大战小游戏

    Vue实现飞机大战小游戏

    这篇文章主要为大家详细介绍了Vue实现飞机大战小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • 使用Vue Composition API写出清晰、可扩展的表单实现

    使用Vue Composition API写出清晰、可扩展的表单实现

    这篇文章主要介绍了使用Vue Composition API写出清晰、可扩展的表单实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • electron-vue 运行报错 Object.fromEntries is not a function的解决方案

    electron-vue 运行报错 Object.fromEntries is not a function

    Object.fromEntries() 是 ECMAScript 2019 新增的一个静态方法,用于将键值对列表(如数组)转换为对象,如果在当前环境中不支持该方法,可以使用 polyfill 来提供类似功能,接下来通过本文介绍electron-vue 运行报错 Object.fromEntries is not a function的解决方案
    2023-05-05
  • vue中引入高德地图并多点标注的实现步骤

    vue中引入高德地图并多点标注的实现步骤

    这篇文章主要介绍了vue中引入高德地图并多点标注,实现步骤是通过vue的方法引入地图,初始化地图,设置宽和高,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2022-09-09
  • 关于ElementUI的el-upload组件二次封装的问题

    关于ElementUI的el-upload组件二次封装的问题

    这篇文章主要介绍了关于ElementUI的el-upload组件二次封装的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • Vue 使用v-model实现控制子组件显隐效果

    Vue 使用v-model实现控制子组件显隐效果

    v-model 可以实现双向绑定的效果,允许父组件控制子组件的显示/隐藏,同时允许子组件自己控制自身的显示/隐藏,本文给大介绍Vue 使用v-model实现控制子组件显隐,感兴趣的朋友一起看看吧
    2023-11-11

最新评论