Loading

Vue2 插槽

Vue 插槽

概述

插槽就是组件内的一个预留区域,它允许使用者向组件内的预留区域来添加自己想要的内容。

比如我们已经写好了一个组件,然后以后可能会在指定区域插入广告,这时就可以先用插槽进行占位。如果使用者向插槽中传递广告时,这时广告才会显示出来。

插槽大概分为三种:默认插槽、具名插槽、作用域插槽。

插槽通过 <slot></slot>标签,在组件中占位。当标签内没有默认值时,如果使用者使用组件时,不插入自定义内容,那么插槽不会被渲染;如果使用者使用组件插入自定义内容时,插槽才进行渲染。如果插槽中有默认值时,如果插槽不被使用,则会输出默认值。

默认插槽

Skills.vue

<template>
  <div id="skills">
    <h2 id="title">skills</h2>
    <hr />
    <ul>
      <li v-for="(skill, index) in skills" :key="index">{{ skill }}</li>
    </ul>
  	<!-- 默认插槽 -->
    <slot></slot>
  </div>
</template>

<script>
  export default {
    name: "Skills",
    props: ["skills"]
  }
</script>

App.vue

<template>
  <div id="app">
    <div class="header">
      <Skills :skills="skills">
          // 组件标签内的所有内容将会被写到该组件中默认插槽的预留位置
        <h2>默认插槽</h2>
      </Skills>
    </div>
  </div>
</template>

<script>
  import Skills from "./components/Skills.vue"
  export default {
    name: "App",
    components: { Skills },
    data() {
      return {
        skills: ["唱", "跳", "rap", "篮球"]
      }
    }
  }
</script>
  • 注意在书写样式时,结构在哪个文件,样式就书写到哪个文件中。
  • 即使组件标签中的内容是要替换到组件插槽位置的,样式也要在组件标签所在的当前文件中书写。
  • 因为组件标签中的内容是现在本文件渲染,然后才去替换组件插槽处的位置的。

具名插槽

当我们指定多个插槽时,就需要为插槽取名字了。因为默认插槽只能存在一个。

我们在使用插槽传入内容时,必须要使用 template 标签包裹内容,并指定要服务的具名插槽的名字。

Skills.vue

<template>
  <div id="skills">
    <h2 id="title">skills</h2>
    <hr />
    <ul>
      <li v-for="(skill, index) in skills" :key="index">{{ skill }}</li>
    </ul>
    <!-- 默认插槽 -->
    <slot></slot>
    <!-- 具名插槽 -->
    <slot name="slot01"></slot>
  </div>
</template>

<script>
  export default {
    name: "Skills",
    props: ["skills"]
  }
</script>

App.vue

<template>
  <div id="app">
    <div class="header">
      <!-- 默认插槽 -->
      <Skills :skills="skills">
        <h2>默认插槽</h2>
      </Skills>
      <!-- 具名插槽 -->
      <Skills :skills="skills">
        <template v-slot:slot01>
          <div>
            <h2>具名插槽</h2>
          </div>
        </template>
      </Skills>
    </div>
  </div>
</template>

<script>
  import Skills from "./components/Skills.vue"
  export default {
    name: "App",
    components: { Skills },
    data() {
      return {
        skills: ["唱", "跳", "rap", "篮球"]
      }
    }
  }
</script>
  • 具名插槽在插槽标签中使用 name 来给插槽起名字,以达到区分的作用。
  • 具名插槽在组件标签使用时其中的结构必须使用 template 标签包裹,并且在该标签中使用 v-slot:xxxx指定所使用的具名插槽的名字。可以简写成#slot:xxx。注意是冒号:不是等号=

作用域插槽

作用域插槽并不是一种单独的插槽,而是实现插槽向使用者传递数据的一种插槽的称呼。

所以默认插槽可以是作用域插槽,具名插槽也可以是作用域插槽。

Skills.vue

<template>
  <div id="skills">
    <h2 id="title">skills</h2>
    <hr />
    <ul>
      <li v-for="(skill, index) in skills" :key="index">{{ skill }}</li>
    </ul>
    <!-- 默认插槽的作用域插槽 -->
    <slot :data="slotData"></slot>
    <!-- 具名插槽的作用域插槽 -->
    <slot name="slot01" :slotData="slotData"></slot>
  </div>
</template>

<script>
  export default {
    name: "Skills",
    props: ["skills"],
    data() {
      return {
        slotData: {
          content:"此数据由插槽传递给使用者"
        }
      }
    },
  }
</script>

App.vue

<template>
  <div id="app">
    <div class="header">
      <!-- 默认插槽 -->
      <Skills :skills="skills">
        <h2>默认插槽</h2>
      </Skills>
      <!-- 具名插槽 -->
      <Skills :skills="skills">
        <template v-slot:slot01>
          <div>
            <h2>具名插槽</h2>
          </div>
        </template>
      </Skills>
      <!-- 具名插槽作用域插槽:接收插槽组件传给使用者的数据 -->
      <Skills :skills="skills">
        <template #slot01="scope">
          <div>
            <h2>作用域插槽</h2>
            <p>{{ scope }}</p>
            <p>{{ scope.slotData.content }}</p>
          </div>
        </template>
      </Skills>
      <!-- 默认插槽作用域插槽解构赋值 -->
      <Skills :skills="skills">
        <template scope="{data}">
          <p>{{ data }}</p>
          <p>{{ data.content }}</p>
        </template>
      </Skills>
    </div>
  </div>
</template>

<script>
  import Skills from "./components/Skills.vue"
  export default {
    name: "App",
    components: { Skills },
    data() {
      return {
        skills: ["唱", "跳", "rap", "篮球"]
      }
    }
  }
</script>
  • 在插槽标签中,指定属性来向使用者传递值。
  • 使用者可以在 template 标签中接收插槽传递的值。如果是具名插槽使用#slot01="scope"接收,scope 可自定义名字,为接收的数据对象。如果是默认插槽使用scope="scope"接收。其中可以参照上面代码使用 es6 的解构赋值。
posted @ 2022-10-03 13:25  brokyz  阅读(301)  评论(0编辑  收藏  举报