vue 插槽 (v-slot)

1. 插槽指令

  • 父组件给子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段。
  • 使用 v-slot:插槽名称 绑定插槽,简写:#插槽名称
  • 动态插槽名:v-slot 绑定一个变量,可以动态改变插槽名

2. 具名插槽

  • 需要在父组件中使用 v-slot 指令绑定插槽名称
  • 并且在子组件的 <slot> 标签中绑定 name 属性
  • 父组件中使用 v-slot 指令绑定的插槽名和子组件中 <slot> 标签绑定的 name 属性中值要一样
  • 如果子组件存在多个插槽,需要使用具名插槽,以避免插槽内容无法正确的渲染到指定位置
<!-- 父组件 -->
<template>
    <Children>
        <!-- 
            父组件中<template v-slot:header></template> 标签中的内容会渲染到子组件中<slot name="header"></slot>的插槽中 
        -->
        <template v-slot:header>
            <div>我是header</div>
        </template>
    </Children>
</template>
<script lang="ts" setup>
    import Children from "./children.vue";
</script>

<!-- 子组件 -->
<template>
    <div>
        <slot name="header"></slot>
    </div>
</template>

3. 默认插槽

  • 当父组件中没有使用 v-slot 指令绑定插槽名称,直接向子组件传递插槽内容
  • 并且子组件的 <slot> 标签中没有绑定 name 属性
  • 如果子组件中只有一个插槽,可以使用默认插槽
  • 如果子组件的插槽全都没有绑定 name 属性,那么每个插槽都会接收到父组件传递的插槽内容,导致子组件内所有的插槽都是重复的相同的插槽
<!-- 父组件 -->
<template>
    <!--    
        <Children></Children> 标签的中间区域是插槽入口,
        里面的内容会传递给子组件中的<slot></slot>标签中 
    -->
    <Children>插槽内容</Children>
</template>
<script lang="ts" setup>
    import Children from "./children.vue";
</script>

<!-- 子组件 -->
<template>
    <div>
        <!-- 
            <slot></slot> 标签的中间区域是插槽出口,
            用于接收父组件传递过来的插槽内容,
            并将插槽内容在子组件的<slot></slot>标签中渲染 
         -->
        <slot></slot>
    </div>
</template>

<!-- 插槽默认值 -->
<template>
    <div>
        <slot>
            <!-- 
                如果父组件没有传递插槽内容过来,
                就渲染 <p> 标签;
                如果父组件传递了插槽内容过来,
                就渲染接收到的插槽内容
             -->
            <p>插槽默认内容</p>
        </slot>
    </div>
</template>

4. 插槽默认值

  • 如果父组件传递了插槽内容,则渲染父组件传递的内容
  • 如果父组件未传递插槽内容,则渲染插槽的默认内容
<!-- 父组件 -->
<template>
    <!-- 父组件传递了插槽内容,子组件插槽渲染该内容 -->
    <Children>
        <p>父组件传递的插槽内容</p>
    </Children>
    <!-- 父组件为传递插槽内容,子组件渲染默认内容 -->
    <Children></Children>
</template>
<script lang="ts" setup>
    import Children from "./children.vue";
</script>

<!-- 子组件 -->
<template>
    <div>
        <slot>
            <p>插槽默认内容</p>
        </slot>
    </div>
</template>

5. 渲染作用域

  • 子组件的渲染作用域:
    <slot>内容</slot> 标签中间的内容区域外,整个 vue 文件都是子组件的直属区域
  • 父组件的渲染区域:
    整个父组件 vue 文件,以及子组件中 <slot>内容</slot> 标签中间的内容区域

6. 作用域插槽

  • 带有 props<slot> 叫做作用域插槽
  • 父组件通过 v-slot 指令绑定一个变量 slotProps,用于接收子组件传递的数据
  • 子组件通过 v-bind 提供的数据,这些数据会被 <slot> 标签传递给父组件,
  • 变量 slotProps是个对象,子组件提供的数据会存储在其中
  • 插槽上的 name 是一个 Vue 特别保留的 attribute,不会作为 props 传递给插槽
<!-- 具名作用域插槽 -->
<!-- 父组件 -->
<template>
    <div>srud示例</div>
    <Children v-slot:header="slotProps">
        <p>{{ slotProps.count }} + {{ slotProps.count }}</p>
    </Children>
</template>
<script setup>
    import Children from "./children.vue";
</script>
<!-- 子组件 -->
<template>
    <div>
        <!-- 
            1. <slot> 标签会将 count、msg 传递给父组件中 v-slot 绑定的 slotProps
            2. 在父组件中通过slotProps.count、slotProps.count获取子组件传递的count、msg
         -->
        <slot :count="count" :msg="msg" name="header"></slot>
    </div>
</template>
<script lang="ts" setup>
    const count = "子组件数据";
    const msg = "数据2";
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值