vue (vue2) 三种插槽(匿名插槽 具名插槽 作用域插槽)的全面讲解

vue里模板复用使我们的效率大大提升了,可是在复用的时候都需要保留框架而更改内容,这时候就需要用到插槽了

插槽分为:匿名插槽,具名插槽和作用域插槽 (以填詩詞爲例)

匿名插槽:

子模板:

<template>
<div class="slot">
    <span>一朝选在君王侧。</span> 
</template>

引入模板的父组件:

<template>
  <div class="home">
    <v-slot class="fp"> 
      <span>天生丽质难自弃,</span>
    </v-slot>
 </div>
</template> // 使用

import vSlot from '../components/slot.vue' //引入

export default {
components: { vSlot } //注册
}

效果:

 这时候你会发现 哎 我的 “天生丽质难自弃,” 呢?别急 咱先试试匿名插槽

引入父组件不动 只需在子模板合适位置加上一<slot></slot>标签即可

<template>
    <div class="slot">
        <slot></slot>
        <span>一朝选在君王侧。</span>
    </div>
</template>

效果:

 是不是 so easy ! 那如果我不小心加了很多的<slot></slot>标签会怎样?

比如这样?

<template>
    <div class="slot">
        <slot></slot>
        <slot></slot>
        <span>一朝选在君王侧。</span>
        <slot></slot>
        <slot></slot> 
        <slot></slot>
    </div>
</template>

效果:

 那天生丽质 真 · 难自弃 了 由此匿名插槽的弊端暴露无疑:在使用模板时填入的内容都会去找匿名插槽,找到一个就把内容填入,有几个就填几个,就无法避免重复。

快看!这时候具名插槽出现了

具名插槽:

子模板:

<template>
    <div class="slot">
        <p>
            <slot name="footer">
                <span>footer-显示默认内容</span>
            </slot>
        </p>

        <p>
            <slot name="header">
                <span>header-显示默认内容</span>
            </slot>
        </p>
        
        <p>
            <slot></slot>
            <span>一朝选在君王侧。</span>
        </p>


    </div>
</template>

父组件:

<template>
  <div class="home">

 <v-slot class="fp">

        <template v-slot:header>
        </template>
      
        <template #footer>
        </template>
      
      
      <span>天生丽质难自弃,</span>

    </v-slot>

 </div>
</template>
 

效果:

 有个有意思的现象:

在使用具名插槽的时候,我明明先用的header 可为什么footer在前面显示呢?

其实显示的先后的关键在于子模板的排列先后  这和父组件的使用先后无关

也就是说虽然我footer名字起的是差了点,但我在子模板中选了个第一排的好位置,所以显示内容就在第一排(我骄傲 !╭(╯^╰)╮)

那么又一个问题来了:每次使用模板时总不能内容是固定的吧 那具名插槽里的初始默认内容需要根据内容更改的呀

子模板:

<template>
    <div class="slot">
        <slot name="footer">
            <span>footer-显示默认内容</span>
        </slot>
        <slot name="header">
            <span>header-显示默认内容</span>
        </slot>
        
        <p>
            <slot></slot>
            <span>一朝选在君王侧。</span>
        </p>


    </div>
</template>

父组件:

<template>
  <div class="home">

 <v-slot class="fp">

         <template v-slot:header>
          <span>养在深闺人未识。</span>
        </template>
      
        <template #footer>
          <span>杨家有女初长成,</span>
        </template>
      
      
      <span>天生丽质难自弃,</span>

    </v-slot>

 </div>
</template>

效果:

 由此可见:

<template v-slot:header> </template>

<template #header> </template>

这两种还像都可以找到对应名称的插槽,

其实就是全称与简写的区别了 v-slot:可简写成 #

且在里面写入的内容就会取代默认内容 是不是炒鸡简单?

这时候我里面内容是可变的且数据在子模板里怎么办?看!作用域插槽来了

作用域插槽:

子模板

:msg="content"  【msg可用任意名称 我这里用msg】【content是data里定义的数据名称】

这里提一下 如果不小心写成 msg="content" ?那么传递出去的就是content这个字符串数据了

比如你想打个招呼 又不想在data里重新定义 后面也不需要更改 可写成 msg="hello" 把hello这个字符串传递出去

<template>
    <div class="slot">
        <p>
            <slot name="footer">
                <span>footer-显示默认内容</span>
            </slot>

            <slot name="header">
                <span>header-显示默认内容</span>
            </slot>
        </p>

        <p>
            <slot></slot>
            <span>一朝选在君王侧。</span>
        </p>
        
        <p>
            <slot name="content" :msg="content"></slot>
        </p>

    </div>
</template>

字幕版字符串数据数据:

 

父组件:

<template>
  <div class="home">

 <v-slot class="fp">

         <template v-slot:header>
          <span>养在深闺人未识。</span>
        </template>
      
        <template #footer>
          <span>杨家有女初长成,</span>
        </template>
      
      
      <span>天生丽质难自弃,</span>

      <template #content="msg">
            <span>{{msg.msg}}</span>
      </template> 

    </v-slot>

 </div>
</template>

效果:

在展示数据时 msg.msg是不是很烦人呢?如果字段不是字符串而是对象,数组对象甚至嵌套好几次 难道我要一层一层点下去吗?

如此 那我们试一下进阶版

子模板:

注意点:【使用v-for时无需绑定key值,会报错。有知道原理的大佬望不吝赐教】

<template>
    <div class="slot">
        <p>
            <slot name="footer">
                <span>footer-显示默认内容</span>
            </slot>

            <slot name="header">
                <span>header-显示默认内容</span>
            </slot>
        </p>

        <p>
            <slot></slot>
            <span>一朝选在君王侧。</span>
        </p>

        <p>
            <slot name="main" v-for="item in list" :msg="item"></slot>
        </p>

    </div>
</template>

子模板数组数据:

 父组件:

这里原理其实很简单 就是子模板遍历数组 并把遍历的每一项放到msg里然后传递给父组件

父组件接收msg并结构取值 然后展示

<template>
  <div class="home">

 <v-slot class="fp">

         <template v-slot:header>
          <span>养在深闺人未识。</span>
        </template>
      
        <template #footer>
          <span>杨家有女初长成,</span>
        </template>
      
      
      <span>天生丽质难自弃,</span>

       <template v-slot:content="content">
            <span>{{content.content}}</span>
      </template> 
      
       <template #main="{msg}">
            <span>{{msg}}</span>
      </template>

    </v-slot>

 </div>
</template>

效果:

 总结:

所以作用域插槽使用的终极形式就是

<template #main="{msg}"><span>{{msg}}</span></template>

原本 v-slot:main="msg" 进化成 #main="{msg}" 【简写+解构】当然随着数据格式的复杂解构也可以嵌套很多层,或者解构某一位置上的目标值

 

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值