vue2和vue3中插槽写法区别

发布时间 2023-08-14 11:07:15作者: 花粉回家

一、slot是什么

  • 在HTML中 slot 元素 ,作为 Web Components 技术套件的一部分,是Web组件内的一个占位符。
  • 该占位符可以在后期使用自己的标记语言填充。
    (我们可以理解为solt在组件模板中占好了位置,当使用该组件标签时候,组件标签里面的内容就会自动填坑(替换组件模板中slot位置),作为承载分发内容的出口)

二、使用场景

通过插槽可以拓展组件,去更好地复用组件和对其做定制化处理。
例:父组件使用到一个复用组件,但是该组件在不同的地方有少量的区别,若单独为了这不同的地方重写一个组件显然在成本方面是有浪费的,此时我们就可以使用插槽的方式进行设计。
比如布局组件、表格列、下拉选、弹框显示内容等...

三、slot的分类

  • 默认插槽
  • 具名插槽
  • 作用域插槽

四、slot的使用方式

1. vue2.0的使用方式
子组件中定义时:
  • 插槽用<slot>标签来确定渲染的位置,里面放如果父组件没传内容时的后备内容;

  • 具名插槽name属性来表示插槽的名字,不传为默认插槽;

  • 作用域插槽在作用域上绑定属性来将子组件的信息传给父组件使用,这些属性会被挂在父组件slot-scope接受的对象上。

    <!-- Child.vue -->
    <template>
      <div>
        <!-- 默认插槽 -->
        <main>
            <slot>
                <h3>没传内容</h3>
            </slot>
        </main>
    
        <!-- 具名插槽 -->
        <header>
            <slot name="header">
                <h3>没传header插槽</h3>
            </slot>
        </header>
    
        <!-- 作用域插槽 -->
        <footer>
            <slot name="footer" testProps="子组件的值">
                <h3>没传footer插槽</h3>
            </slot>
        <footer>
      </div>
    </template>
    
    <style scoped>
    div {
        border: 1px solid #000;  
    }
    </style>
    
父组件中在使用时:
  • 默认插槽的话直接在子组件的标签内写入内容即可;

  • 具名插槽是在默认插槽的基础上加上slot属性,值为子组件插槽name属性值;

  • 作用域插槽则是通过slot-scope获取子组件的信息,在内容中使用。且这里可以用解构语法去直接获取想要的属性。

    <!-- Parent.vue -->
    <child>
      <!-- 默认插槽 -->
      <div>默认插槽</div>  
      <!-- 具名插槽 -->
      <div slot="header">具名插槽header</div>
      <!-- 作用域插槽 -->
      <div slot="footer" slot-scope="slotProps">
        {{slotProps.testProps}}
      </div>
    </child>
    
渲染结果

2. vue3.0的使用方式

在vue2.6中,上述的API被软废弃(3.0正式废弃),取而代之的是内置指令v-slot,可以缩写为【#】

子组件用法保持不变,父组件中
  • slot属性弃用。具名插槽通过指令参数v-slot:插槽名 的形式传入,可以简化为 #插槽名默认插槽名为defaul,可以省略default直接写v-slot,缩写为#时不能不写参数,简写成#default
  • 多个插槽混用时,v-slot不能省略default
  • v-slot属性只能在<template>上使用,但在【只有默认插槽时】可以在组件标签上使用;
  • slot-scope属性弃用,作用域插槽通过v-slot:插槽名="slotProps"的slotProps来获取子组件传出的属性;
  • 可以通过解构获取v-slot={user},还可以重命名v-slot="{user: newName}"和定义默认值v-slot="{user = '默认值'}"
<!-- Parent.vue -->
<template >
    <child>
        <!--默认插槽-->
        <template v-slot>
            <div>默认插槽</div>
        </template>

        <!--具名插槽-->
        <template #header>
            <div>具名插槽</div>
        </template>

        <!--作用域插槽-->
        <template #footer="slotProps">
            <div>
                {{slotProps.testProps}}
            </div>
        </template>
    <child>
</template>