Vue——插槽

Vue——插槽

一、插槽的基本使用

插槽的作用:

Vue插槽是Vue中常见的一种组件间的相互通信方式,作用是让父组件可以向子组件指定位置插入html结构,适用于父组件===>子组件,在要接收数据的组件页面通过标签来表示,简单来说,就是通过此标签来起到占位的作用,而要插入的内容也会对应到标签所在的位置

插槽的基本使用:

这里我们选定App.vue作为父组件,Card.vue作为子组件,作为演示插槽基本使用的代码文件。

如下:

App.vue

<template>
  <div>
    <Card>
      <div>这是插槽插入的内容</div>
    </Card>
	------------------------
    <Card> </Card>
  </div>
</template>

<script>
import Card from "./components/Card.vue";
export default {
  components: { Card },
};
</script>

Card.vue

<template>
  <div>插槽的基本使用</div>
  <div style="color: red">
    <slot>没有插入内容时显示的默认数据</slot>
  </div>
  <!-- 可以插入多个 -->
  <slot>没有插入内容时显示的默认数据</slot>
  <slot>没有插入内容时显示的默认数据</slot>
</template>

<script>
export default {};
</script>

运行结果:

Vue——插槽_第1张图片

从上面的运行结果可以看到,插槽的基本使用是子组件自身内容正常显示,插入的内容是父组件向子组件插入的内容,并且插入的内容可以显示多条,如果没有插入内容,将显示标签内的默认数据,另外标签外也可以另外用其他html标签包裹并增加样式。

总结:

  1. 标签用于接收并展示父组件插入的内容。
  2. 标签可以重复使用。
  3. 标签外可以使用其他html标签包裹,与其他html标签没有很大区别。
  4. 标签内可以插入默认显示的内容,当插槽内容为空时显示。

二、插槽作用域

插槽无论写在哪个父组件中,它所能使用的方法和属性就是该父组件中的方法和属性,跟插槽最终放置在的子组件没有关系,子组件若要使用父组件中的方法和属性,可以通过插槽绑定属性和方法,子组件内使用props接收。下面我们通过代码了体会。

App.vue

<template>
  <div>
    <Card :content="content">
      <button @click="show">{{ content }}</button>
    </Card>
  </div>
</template>

<script>
import Card from "./components/Card.vue";
export default {
  components: { Card },
  data() {
    return {
      content: "父组件的数据",
    };
  },
  methods: {
    show() {
      console.log("父组件的show");
    },
  },
};

Card.vue

<template>
  <h2>插槽的作用域</h2>
  <slot>没有插入内容时显示的默认数据</slot>
  <div>{{ content }}</div>
</template>

<script>
export default {
  props: ["content"],
  methods: {
    show() {
      console.log("子组件的show");
    },
  },
};
</script>

运行结果:

Vue——插槽_第2张图片

可以看到,父组件和子组件具有相同的方法show(),点击父组件的数据按钮,输出的是父组件中show()方法的结果,子组件通过props成功获取父组件的content数据并展示。

总结:

  1. 插槽在哪个父组件,插槽所能使用的方法和属性就是该父组件的方法和属性。
  2. 子组件要使用父组件的属性和方法可以通过插槽绑定属性和方法,使用props接收。

三、具名插槽

简单来说,所谓的具名插槽就是具有名字的插槽

那它和默认插槽的区别在哪呢?

我们经常会遇到这样的场景,多个类似的结构复用同一个组件,但是这些结构又有一些不同。如下图,左侧和右侧的结构复用同一个组件,可以看到左上角的内容以及下方的结构是不同的,左上角的标题我们通过普通插槽传入不同的数据可以实现展示不同标题,但是下面的主体结构如果还使用普通插槽的话,那么将会呈现相同的结构;这时,我们就需要具名插槽了,根据不同的结构,定义不同的插槽,并赋予名字,以便于调用。

Vue——插槽_第3张图片

下面我们通过代码来理解什么是具名插槽以及具名插槽如何使用

App.vue

<template>
  <div>
    <Card>
      <template v-slot:header>
        <div>
          这是具名插槽header,想放啥就放啥,很灵活
          <div
            style="background-color: #ddd; width: 100px; height: 100px"
          ></div>
        </div>
      </template>
      <template #main>
        <div>这是具名插槽main,想放啥就放啥,很灵活</div>
        <div style="background-color: #000; width: 100px; height: 100px"></div>
      </template>
    </Card>
    --------------------------------------------------------
    <Card>
      <template v-slot:header>
        <div>这是具名插槽header,想放啥就放啥,很灵活</div>
      </template>
      <template #main>
        <div>这是具名插槽main,想放啥就放啥,很灵活</div>
      </template>
      <template #footer>
        <div>这是具名插槽footer,想放啥就放啥,很灵活</div>
      </template>
    </Card>
    ---------------------------------------------------------
    <Card>
      <template v-slot:header>
        <div>这是具名插槽header</div>
      </template>
      <template #main>
        <div>这是具名插槽main</div>
      </template>
      <template #footer>
        <div>这是具名插槽footer</div>
      </template>
    </Card>
  </div>
</template>

<script>
import Card from "./components/Card.vue";
export default {
  components: { Card },
};

Card.vue

<template>
  <div class="card">
    <header>
      <slot name="header">默认数据</slot>
    </header>
    <main>
      <slot name="main">默认数据</slot>
    </main>
    <footer>
      <slot name="footer">默认数据</slot>
    </footer>
  </div>
</template>

<script>
export default {};
</script>

<style scoped>
.card {
  border: solid 1px #ddd;
}
header,
main,
footer {
  padding: 10px;
}
main {
  border-width: 1px 0 1px 0;
  border-style: solid;
  background-color: #ddd;
}
</style>

运行结果:

Vue——插槽_第4张图片

可以看到根据需求不同,使用具名插槽可以传入不同的结构,提升了组件使用的灵活性。

总结:

  1. 父组件使用