vue中的插槽--slot和v-slot

本文介绍了Vue中的插槽机制,包括默认插槽、具名插槽、作用域插槽及其在vue@2.6.x后的v-slot新语法。通过示例展示了如何使用v-slot替代老的slot和slot-scope,强调了v-slot的使用规则以及其在模板分块和组件重用中的重要性。

今天团队内部有一个技术分享会,主要是vue进阶这一块,我对插槽slot的认识还不清晰,于是就总结一下
什么是插槽?
插槽(Slot)是Vue提出来的一个概念,正如名字一样,插槽用于决定将所携带的内容,插入到指定的某个位置,从而使模板分块,具有模块化的特质和更大的重用性。
插槽显不显示、怎样显示是由父组件来控制的,而插槽在哪里显示就由子组件来进行控制

从 vue@2.6.x 开始,Vue 为具名和范围插槽引入了一个全新的语法,即我们今天要讲的主角:v-slot 指令。目的就是想统一 slot 和 slot-scope 语法,使代码更加规范和清晰。既然有新的语法上位,很明显,slotscope-slot 也将会在 vue@3.0.x 中彻底的跟我们说拜拜了。而从 vue@2.6.0 开始,官方推荐我们使用 v-slot 来替代后两者。

跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header:

下面我们将用之前的slot的默认插槽,具名插槽,作用域插槽 和最新的v-slot做对比记忆

怎么用插槽?

1.默认插槽

1.1 老的写法

子组件(slotOne1)

 <template>
      <div class="slotOne1">
        <div>我是slotOne1组件</div>
        <slot></slot>
      </div>
    </template>

在子组件中写入slot,slot所在的位置就是父组件要显示的内容

父组件

 <template>
      <div>
        我是父组件
        <slotOne1>
          <p style="color:red">我是父组件插槽内容</p>
        </slotOne1>
      </div>
    </template>

在父组件引用的子组件中写入想要显示的内容(可以使用标签,也可以不用)
结果展示
1.2 用v-slot实现(新的方法)

子组件(slotOne1)

 <template>
      <div class="slotOne1">
        <div>我是slotOne1组件</div>
        <slot></slot>
      </div>
    </template>

在子组件中写入slot,slot所在的位置就是父组件要显示的内容

父组件

 <template>
      <div>
        我是父组件
        // 当然也可以不写v-slot:default  直接<slotOne1>
        <slotOne1 v-slot:default>
          <p style="color:red">我是父组件插槽内容</p>
        </slotOne1>
      </div>
    </template>

Tips: 没有名字的 隐含有一个 “default” 名称
任何没有被包裹在带有 v-slot 的 组件标签 中的内容都会被视为默认插槽的内容。
在父组件引用的子组件中写入想要显示的内容(可以使用标签,也可以不用)
展示

当然在父组件引用的子组件中也可以写入其他组件 例如:

子组件(slotOne1)

<template>
   <div class="slotOne1">
      <div>我是slotOne1组件</div>
      <slot></slot>
   </div>
</template>

子组件(slotOne2)

 <template>
      <div class="slotOne2">
        我是slotOne2组件
      </div>
    </template>

父组件

<template>
  <div>
    我是父组件
    <slotOne1>
      <p style="color:red">我是父组件插槽内容</p>
      <slot-one2></slot-one2>
    </slotOne1>
  </div>
</template>

结果如下
2.具名插槽

2.1 老的写法
子组件(slotTwo)

<template>
  <div class="slottwo">
    <div>slottwo</div>
    <slot name="header"></slot>
    <slot></slot>
    <slot name="footer"></slot>
  </div>
</template>

在子组件中定义了三个slot标签,其中有两个分别添加了name属性header和footer

父组件

 <template>
      <div>
        我是父组件
        <slot-two>
          <p>啦啦啦,啦啦啦,我是卖报的小行家</p>
          <template slot="header">
              <p>我是name为header的slot</p>
          </template>
          <p slot="footer">我是name为footer的slot</p>
        </slot-two>
      </div>
    </template>

在父组件中使用template并写入对应的slot值来指定该内容在子组件中现实的位置(当然也不用必须写到template),没有对应值的其他内容会被放到子组件中没有添加name属性的slot中

展示结果
2.2 新的写法
子组件(slotTwo)

<template>
  <div class="slottwo">
    <div>slottwo</div>
    <slot name="header"></slot>
    <slot></slot>
    <slot name="footer"></slot>
  </div>
</template>

在子组件中定义了三个slot标签,其中有两个分别添加了name属性header和footer

父组件

 <template>
      <div>
        我是父组件
        <slot-two>
          <template #header>
              <p>我是name为header的slot</p>
          </template>
        //<p>啦啦啦,啦啦啦,我是卖报的小行家</p>  // 不用template标签也可以   会添加到默认插槽中
          <template #default>
              <p>啦啦啦,啦啦啦,我是卖报的小行家</p>
          </template>
           // 请注意, v-slot 只能添加到 <template> 或自定义组件上,这点与弃用的 slot 属性不同   这里使用了缩写#  v-slot的缩写是#
           //<p #footer>我是name为footer的slot</p>  不能这样写
           // 要这样写
           <template #footer>
              <p>我是name为footer的slot</p>
          </template>
        </slot-two>
        // 或者用以下的格式
         <slot-two>
          <template v-slot:header>
              <p>我是name为header的slot</p>
          </template>
          <template v-slot:default>
              <p>啦啦啦,啦啦啦,我是卖报的小行家</p>
          </template>
           <template  v-slot:footer>
              <p>我是name为footer的slot</p>
          </template>
        </slot-two>
      </div>
    </template>

请注意, v-slot 只能添加到 或自定义组件上,这点与弃用的 slot 属性不同 v-slot:的缩写是#
还有就是要么都用v-slot: 要么都用缩写#,不要混合用,要不然只有最后面的才生效
在父组件中使用template并写入对应的slot值来指定该内容在子组件中现实的位置(当然也不用必须写到template),没有对应值的其他内容会被放到子组件中没有添加name属性的slot中

展示插槽的默认内容

子组件(slotTwo2)

<template>
  <div class="slottwo">
    <slot>啦啦啦,啦啦啦,我是卖报的小行家</slot>
  </div>
</template>

父组件

<template>
  <div>
    我是父组件
    <slot-two2></slot-two2>
  </div>
</template>

展示结果
编译作用域

子组件(slotThree)

 <template>
      <div class="slotthree">
        <slot></slot>
      </div>
    </template>

父组件

 <template>
      <div>
        我是父组件
        <slot-three>
          <p>{{name}}</p>
        </slot-three>
      </div>
    </template>
    <script>
    export default {
      data () {
        return {
          name: 'Jack'
        }
      }
    }
    </script>

展示图片
3.作用域插槽

3.1 老的写法
子组件(slotFour)

<template>
  <div>
    我是作用域插槽的子组件
    <slot :data="user"></slot>
  </div>
</template>

<script>
export default {
  name: 'slotfour',
  data () {
    return {
      user: [
        {name: 'Jack', sex: 'boy'},
        {name: 'Jone', sex: 'girl'},
        {name: 'Tom', sex: 'boy'}
      ]
    }
  }
}
</script>

在子组件的slot标签上绑定需要的值

父组件

<template>
  <div>
    我是作用域插槽
    <slot-four>
      <template slot-scope="user">
        <div v-for="item in user.data" :key="item.id">
        // item in user.data这里的user.data中的data一定是要加的,不加显示不出来 谨记
        {{item}}
        </div>
      </template>
    </slot-four>
  </div>
</template>

在父组件上使用slot-scope属性,user.data就是子组件传过来的值
展示图片
3.2 新的写法
子组件(slotFour)

 <template>
      <div>
        我是作用域插槽的子组件
        <slot :data="user"></slot>
      </div>
    </template>
    
    <script>
    export default {
      name: 'slotfour',
      data () {
        return {
          user: [
            {name: 'Jack', sex: 'boy'},
            {name: 'Jone', sex: 'girl'},
            {name: 'Tom', sex: 'boy'}
          ]
        }
      }
    }
    </script>

在子组件的slot标签上绑定需要的值

父组件

<template>
  <div>
    我是作用域插槽
    <slot-four>
    //<template v-slot:default="user"> 也可以这样写,下面是简写  v-slot 和 v-shot:default 是一样的效果。但当遇到缩写形式时需要显示调用。
      <template v-slot="user">
        <div v-for="item in user.data" :key="item.id">
        {{item}}
        </div>
      </template>
    </slot-four>
  </div>
</template>

user.data就是子组件传过来的值
展示图片
感谢这篇文章的帮助vue中的插槽————slot
有一篇文章写的不错Vue.js 你需要知道的 v-slot (译)

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值