插槽(slot)

340 阅读2分钟

插槽是什么?

插槽可以想象为小霸王游戏机的游戏卡,当游戏卡没有名字时就是默认插槽,当我们给每张游戏卡命名时就是具名插槽,而后面的一张游戏卡有几百种游戏就是作用域插槽

一、定义插槽

  • 插槽的使用过程其实是抽取共性,保留不同
  • 我们会将共同的元素、内容依然在组件内进行封装
  • 同时会将不同的元素使用slot作为占位,让外部决定到底显示什么元素

二、使用插槽

  • Vue中将 slot 元素作为承载分发内容的出口
  • 在封装组件中,使用特殊的 slot 就可以为封装组件开启一个插槽
  • 该插槽插入什么内容取决于父元素如何使用

具名插槽

一.具名插槽的使用

  • 具名插槽就是给插槽起一个名字,slot 元素有一个特殊的 属性:name;
  • 在向具名插槽提供内容的时候,我们可以在一个 template 元素上使用 v-slot 指令,并以 v-slot 的参数的形式提供其名称
<template><div> <nav-bar>
 <template v-slot:left><button>左边按钮</button></template>
 <template v-slot:center><h2>中间标题</h2></template> 
 <template v-slot:right><i>右边i元素</i></template>
</nav-bar></div></template>
  • 插槽的使用过程如下:
<slot name=’left’>左边按钮</slot>
<slot name=’center’>中间标题</slot>
<slot name=’right’>右边i元素</slot>
  • 动态插具名插槽使用的时候缩写
<template><div>
<nav-bar><template #left><button>左边按钮</button></template>
<template #center><h2>中间标题</h2></template>
<template #right><i>右边i元素</i></template>
</nav-bar></div></template>

作用域插槽

  • 让插槽内容能够访问子组件中才有的数据
  • 我们把需要传递的内容绑到 slot 上,然后在父组件中用v-slot设置一个值来定义我们提供插槽的名字
  • slot-scope
子组件
<slot :data=’data’></slot>

data:[{name:xxx,age:18},{name:xx,age:20}]
父组件
<template  slot-scope=’user’>{{user.data.name}}</template>
  • 新写法  让data在父级插槽内容中使用,可以将data作为slot的一个属性绑定上去 
<span><slot v-bind:data=“data"></slot></span>
  • 绑定在 slot 元素上的 属性 被称为插槽 prop,现在在父级作用域中,我们可以使用带值的v-slot 来定义我们提供的插槽 prop 的名字 v-slot:default=“slotProps”> ‘slotProps’ 命名可以任意
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template> 
</current-user>
  • 独占默认插槽 如果我们的插槽是默认插槽default,那么在使用的时候 v-slot:default="slotProps"可以简写为v-slot="slotProps" 
<show-names
:names="names">
<template v-slot="slotProps">
<span>{{slotProps.item}}-{{slotProps.index}}</span>
</template>
</show-names>

并且如果我们的插槽只有默认插槽时,组件的标签可以被当做插槽的模板来使用,这样,我们就可以将 v-slot 直接用在组件上 

<show-names :names="names" v-slot="slotProps">
<span>{{slotProps.item}}-{{slotProps.index}}</span>
</show-names>
  • 解构插槽Prop
<current-user v-slot="{data }">
{{data. name }}
</current-user>
  • 可以重命名
<current-user v-slot="{data:person }">
{{person. name }}
</current-user>
  • 可以定义默认内容
<current-user v-slot="{data:{name:’eps’} }">
{{data. name }}
</current-user>