Vue中的插槽Slot技术详解

 更新时间:2023年09月18日 09:13:40   作者:牛哥说我不优雅  
插槽(Slot)技术是一种用于组件化开发的重要技术,允许我们在组件中定义一些占位符,在Vue中,插槽的使用方式可以分为三种:默认插槽、具名插槽和作用域插槽,下面我们就来看看这三种方式的具体使用吧

一、引言

Vue.js是一款流行的前端框架,提供了强大的组件化功能。其中,插槽(Slot)技术是一种用于组件化开发的重要技术,允许我们在组件中定义一些占位符,然后在使用组件时,通过插槽来传递内容。插槽的灵活性使得我们可以轻松地定制组件的外观和行为,可以帮助我们更好地处理组件的可复用性和灵活性。

二、插槽基础使用

在Vue中,插槽的使用方式可以分为三种:默认插槽、具名插槽和作用域插槽。

1. 默认插槽

默认插槽是最简单的插槽形式,它允许我们将组件的内容传递到组件内部的一个占位符中。在组件的模板中使用定义默认插槽,然后在使用组件时,将内容传递给这个插槽。

// Com01.vue
<template>
  <h2>学习插槽</h2>
  <div>
    <slot>我是默认插槽,没给我传内容就会默认显示这句话</slot>
  </div>
</template>
// 父组件App.vue
<template>
  <Com01>
    <p>你好,世界!</p>
    <!-- <p>你好,世界!</p> -->
  </Com01>
</template>
<script setup>
import Com01 from './components/Com01.vue'
</script>

在上面的代码示例中,<slot></slot>表示一个默认插槽,将传递给Com01组件的内容放置在这个插槽中。如果把p标签那一行注释掉,就会显示默认内容。

2. 具名插槽

具名插槽允许我们在组件中定义多个插槽,并且可以根据插槽的名称来传递内容。在组件的模板中使用<slot name="slotName"></slot>定义具名插槽,然后在使用组件时,使用<template v-slot:slotName>或者<template slot="slotName">来传递内容给指定的插槽。

// 子组件 Com02.vue
<template>
  <div>
    <slot name="header"></slot>
    <div class="content">
      <slot></slot>
    </div>
    <slot name="footer"></slot>
  </div>
</template>
// 父组件 App.vue
<template>
  <Com02>
    <template v-slot:header>
      <h2>我是头部内容!</h2>
    </template>
    <h2>你好,世界!</h2>
    <template v-slot:footer>
      <h2>我是底部内容!</h2>
    </template>
  </Com02>
</template>
<script setup>
import Com02 from './components/Com02.vue'
</script>

3. 作用域插槽

作用域插槽是一种特殊的插槽,它允许我们在插槽内部访问组件实例的数据,允许父组件将数据传递到子组件中,并在子组件中使用。在组件的模板中使用<slot name="slotName" v-bind:slotData="data"></slot>定义作用域插槽,并在使用组件时,使用<template slot="slotName" v-slot="scope">来访问插槽内部的数据。

// 子组件 Category.vue
<template>
  <div class="category">
    <h3>{{title}}分类组件</h3>
    <slot :foods="foods" :games="games" :films="films">我是插槽1</slot>
  </div>
</template>
<script>
export default {
  name: "Category",
  props: ["title"],
  data(){
    return {
      foods: ["红烧肉","番茄炒蛋","鱼香肉丝"],
      games: ["红色警戒", "穿越火线", "魔兽世界"],
      films: ["肖申克的救赎", "火影忍者", "泰坦尼克号"]
    }
  }
}
</script>
// 父组件 App.vue
<template>
  <div class="container">
    <Category title="食物" >
      <template v-slot="scope">
        {{ scope }}
      </template>
    </Category>
  </div>
</template>
<script>
import Category from './components/Category.vue'
export default {
  name: "App",
  components: {Category},
}
</script>

可以看到父组件中拿到的scope就是一个对象,包括了子组件中传来的三个数组,我们可以自己选择展示哪些数据。

// 父组件 App.vue
<template>
  <div class="container">
    <Category title="食物" >
      <template v-slot="scope">
        <ul>
          <li v-for="item in scope.foods">{{ item }}</li>
        </ul>
      </template>
    </Category>
  </div>
</template>
<script>
import Category from './components/Category.vue'
export default {
  name: "App",
  components: {Category},
}
</script>

三、插槽的高级用法

1. 具名作用域插槽

具名作用域插槽的工作方式也是类似的,插槽props可以作为v-slot指令的值被访问到:v-slot:header="props",也可以直接缩写成#header="props",这是缩写形式。

// 子组件 Category02.vue
<template>
  <div class="category">
    <h3>{{title}}分类组件</h3>
    <slot name="header" :foods="foods" >我是插槽1</slot>
    <slot name="center" :games="games" >我是插槽2</slot>
    <slot name="footer" :films="films" >我是插槽3</slot>
  </div>
</template>
<script>
export default {
  name: "Category",
  props: ["title"],
  data(){
    return {
      foods: ["红烧肉","番茄炒蛋","鱼香肉丝"],
      games: ["红色警戒", "穿越火线", "魔兽世界"],
      films: ["肖申克的救赎", "火影忍者", "泰坦尼克号"]
    }
  }
}
</script>
// 父组件 App.vue
<template>
  <div class="container">
    <Category title="食物游戏电影" >
      <template v-slot:header="scope">
        <ul>
          <li v-for="item in scope.foods">{{ item }}</li>
        </ul>
      </template>
      <template v-slot:center="props">
        <ul>
          <li v-for="(item,index) in props.games" :key="index">{{ item }}</li>
        </ul>
      </template>
      <template #footer="scope">
        <ul slot="center">
          <li v-for="(item,index) in scope.films" :key="index">{{ item }}</li>
        </ul>
      </template>
    </Category>
  </div>
</template>
<script>
import Category from './components/Category02.vue'
export default {
  name: "App",
  components: {Category},
}
</script>

2. 动态插槽名

动态插槽是一种动态地选择插槽名称的方式。我们可以根据组件的状态或属性来决定使用哪个插槽,可以动态地决定将内容插入到哪个具名插槽中。

// 子组件 Com06.vue 
<template>
  <div>
    <button @click="toggleSlot">切换插槽</button>
    <slot :name="currentSlot"></slot>
  </div>
</template>
<script>
export default {
  data() {
    return {
      currentSlot: 'default666',
    };
  },
  methods: {
    toggleSlot() {
      this.currentSlot = this.currentSlot === 'default666' ? 'custom666' : 'default666';
    },
  },
};
</script>
// 父组件 App.vue
<template>
  <div>
    <Com06>
      <template v-slot:default666>
        <p>这是默认内容!</p>
      </template>
      <template v-slot:custom666>
        <p>这是自定义内容!</p>
      </template>
    </Com06>
  </div>
</template>
<script>
import Com06 from './components/Com06.vue'
export default {
  name: "App",
  components: {Com06},
}
</script>

我们在组件中添加了一个按钮,并在按钮的点击事件处理程序中切换currentSlot的值。当按钮被点击时,currentSlot的值会从default切换到custom,或者从custom切换到default,从而实现默认内容和自定义内容的切换。

在父组件中使用这个组件时,可以根据currentSlot的值来动态地指定插槽名称。

3. 插槽内容的访问

可以通过this.$slots访问到插槽的内容。

<template>
  <div>
    <button @click="toggleSlot">切换插槽</button>
    <slot :name="currentSlot"></slot>
  </div>
</template>
<script>
export default {
  data() {
    return {
      currentSlot: 'default666',
    };
  },
  methods: {
    toggleSlot() {
      console.log("this.$slots: ", this.$slots);
      console.log("this.$slots.default666: ", this.$slots.default666);
      console.log("this.$slots.custom666: ", this.$slots.custom666);
    },
  },
};
</script>

四、插槽的本质

其实从打印结果可以看出,slot本质就是Proxy代理的对象,属性名就是各个插槽的名字,属性值就是对应的函数,调用函数得到的结果就是虚拟结点。

<slot name="slot1"></slot>就相当于在调用属性名为slot1的函数,<slot name="slot2" msg="你好世界!"></slot>就相当于在调用属性名为slot2的函数,该函数接收了msg的参数。

插槽的注意事项

插槽内容可以是任意类型,包括HTML、组件等。

默认插槽可以不用写name属性,具名插槽必须写name属性。

作用域插槽传递的数据可以根据需要命名。

五、最后的话

插槽技术是Vue.js中重要的组件化特性之一,为我们提供了灵活的组件化开发方式,通过合理使用插槽,我们可以轻松地定制和扩展组件的功能,使组件的可复用性和灵活性大大提高。

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

相关文章

  • 代码详解Vuejs响应式原理

    代码详解Vuejs响应式原理

    这篇文章主要介绍了代码详解Vuejs响应式原理的基础知识,有兴趣的朋友们参考学习下吧。
    2017-12-12
  • 前端主流框架vue学习笔记第二篇

    前端主流框架vue学习笔记第二篇

    一步一步学Vue,这篇文章为大家分享了第二篇前端主流框架vue学习笔记,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-07-07
  • Vue项目使用px2rem方法示例详解

    Vue项目使用px2rem方法示例详解

    这篇文章主要为大家介绍了Vue项目使用px2rem的方法示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Vue中使用vue-count-to(数字滚动插件)详细教程

    Vue中使用vue-count-to(数字滚动插件)详细教程

    这篇文章主要给大家介绍了关于Vue中使用vue-count-to(数字滚动插件)的相关资料,最近需要开发一个数字滚动效果,在网上找到一个关于vue-countTo的插件,觉得这个插件还不错,需要的朋友可以参考下
    2023-09-09
  • 基于vue-seamless-scroll实现无缝滚动效果

    基于vue-seamless-scroll实现无缝滚动效果

    这篇文章主要为大家详细介绍了基于vue-seamless-scroll实现无缝滚动效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-04-04
  • Vue3实现折叠面板组件的示例代码

    Vue3实现折叠面板组件的示例代码

    折叠面板大家都不陌生,很多时候需要实现一些复杂的交互,就会用到它,简洁直观还美观,下面就跟随小编一起学习一下如果使用Vue3实现折叠面板组件吧
    2024-01-01
  • Vue scoped及deep使用方法解析

    Vue scoped及deep使用方法解析

    这篇文章主要介绍了Vue scoped及deep使用方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • Vue中使用Element UI的Table组件实现嵌套表格功能

    Vue中使用Element UI的Table组件实现嵌套表格功能

    这篇文章主要介绍了Vue中使用Element UI的Table组件实现嵌套表格功能,演示如何在Vue中使用Element UI的Table组件实现嵌套表格,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01
  • Vue.js中computed的基本使用方法

    Vue.js中computed的基本使用方法

    Vue.js中,computed属性根据依赖进行缓存,只有依赖改变时才重新计算,这样有效提高性能,computed属性是响应式的,可以自动更新,并且默认是只读的,它与methods的主要区别在于计算属性具有缓存性,而方法每次调用都会执行,使用computed可以使模板更加简洁,提高应用性能
    2024-09-09
  • vue中的el-form表单rule校验问题(特殊字符、中文、数字等)

    vue中的el-form表单rule校验问题(特殊字符、中文、数字等)

    这篇文章主要介绍了vue中的el-form表单rule校验问题(特殊字符、中文、数字等),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05

最新评论