如何在Vue中使用slot定义组件

(一)前言

在react中,可以将组件理解为上下层级,使用children在子层级作为嵌套渲染,但是vue提供方案为slot,并且相对于react,还提供插槽的扩展功能,主要分为三种,匿名插槽(类似与children),具名插槽,作用域插槽 (可以提供数据绑定)。

(二) 匿名插槽

类似与react的children。

我们举个粟子。

首先我们写个组件如下

<template>
  <div class="demo-view">
    <div>这是子组件</div>
    <slot></slot>
  </div>
</template>

这时候我们在父组件调用就是这样

<Demo>
   <div style="color: blue;">这是嵌套内部组件</div>
 </Demo>

那么显示是怎么样的
如何在Vue中使用slot定义组件
嵌套的html模板最为子元素传递进入,那么如何嵌套,将不会显示slot标签。

(三) 具名插槽

顾名思义就是给子组件slot提供标识的name,场景可以定义不同的插槽,根据名字实现外部组件选择显示什么。

我们来扩展上面的组件

<template>
  <div class="demo-view">
    <div>这是子组件</div>
    <slot>匿名插槽默认值</slot>
    <slot name="up">具名插槽up默认值</slot>
    <slot name="down" style="color: blue;">具名插槽down默认值</slot>
  </div>
</template>

这时候我们在父组件调用就是这样

<Demo>
  <div style="color: blue;">这是嵌套内部组件</div>
  <div slot="up" style="color: red;">这是嵌套up的内部组件</div>
</Demo>

那么显示结果是怎样?

如何在Vue中使用slot定义组件
从结果我们可以看出来一下结果:

  1. 如果不传down时候,插槽会使用默认值显示
  2. 父组件不传slot的名字,会默认使用匿名插槽,顾名思义
  3. 当传入up,会覆盖up插槽的默认值
  4. 即使我们给插槽down设置了样式,样式也不会生效
  5. 拥有命名的插槽不能被不含slot属性的标签内容替换,会显示slot的默认值(具名slot具有对应性);

(四) 作用域插槽

相对于其他两个,作用域插槽需要绑定数据,也可以理解为带数据的插槽。

我们首先改造组件

<template>
  <div class="demo-view">
    <div>这是子组件</div>
    <slot
      v-for="(item, index) in data"
      :row="item"
      :index$="index"
      name="item"
    >
      slot的默认内容
    </slot>
  </div>
</template>

<script>
export default {
  name: 'Demo',
  props: {
    data: {
      type: Array,
      default: () => ['zhangsan', 'lisi', 'wanwu', 'zhaoliu', 'tianqi', 'xiaoba'],
    },
  },
  data() {
    return {
    };
  },
};
</script>

<style lang="scss" scoped>
  .demo-view {
    display: flex;
  }
</style>

然后在父级调用

<Demo>
   <template slot="item" scope="{row}">
     <li>{{row}}</li>
   </template>
 </Demo>

那么现在是怎么显示的呢

如何在Vue中使用slot定义组件

作用域插槽代表性的用例是列表组件,允许在parent父组件上对列表项进行自定义显示,如下该items的所有列表项都可以通过slot定义后传递给父组件使用,也就是说数据是相同的,不同的场景页面可以有不同的展示方式: