插槽

vue 2.6后,插槽变动了,推荐使用最新版写法。

创建一个插槽

<slot></slot>  //默认插槽
<slot name="demo"></slot>  //具名插槽

使用插槽

假设插槽的组件标签为:ddd

<ddd>
  <span>我会被插入默认插槽</span>
  <template v-slot:demo>
    <span>我会被插入demo插槽</span>
  </template>
</ddd>

2.6的插槽,他必须是一个template元素包裹,template上使用v-slot指明插槽名。

简写

v-slot写起来很繁琐,当然会有简写形式

<ddd>
  <span>我会被插入默认插槽</span>
  <template #demo>
    <span>我会被插入demo插槽</span>
  </template>
</ddd>

后面跟着插槽名即可,极度方便,用了就回不来了。

作用域

ddd组件里面的slot,它与组件本身数据是不在同一个作用域的,因为slot内容,是通过另一个组件或者页面,在调用ddd时,插入的,而插入的内容,是无法直接访问ddd组件的数据的。

如:

ddd组件

<template>
  <div>
    <slot></slot>
  </div>
</template>
<script>
export default {
  data(){
    return {
      title:"我是子组件"
    }
  }
}
</script>

调用ddd组件的页面或组件

<template>
  <ddd>
    <span>{{title}}</span>
  </dddd>
</template>
<script>
import ddd from "./ddd";
export default {
  data(){
    return {
      title:"我是父组件"
    }
  },
  components:{
    ddd 
  }
}
</script>

渲染出来后:

<div>
  <span>我是父组件</span>
</div>

插槽无法直接获取到插槽所在子组件内的数据。

作用域插槽(插槽获取子组件中才有的数据)

简单点来说,就是ddd里面的插槽获取ddd里面的数据

ddd组件

<template>
  <div>
    <slot :title="title"></slot>
  </div>
</template>
<script>
export default {
  data(){
    return {
      title:"我是子组件"
    }
  }
}
</script>

调用ddd组件的页面或组件

<template>
  <ddd v-slot:default="title">
    <span>{{title}}</span>
  </dddd>
</template>
<script>
import ddd from "./ddd";
export default {
  data(){
    return {
      title:"我是父组件"
    }
  },
  components:{
    ddd 
  }
}
</script>

渲染出来后:

<div>
  <span>{title:"我是子组件"}</span>
</div>

你会发现v-slot:default="title"的这个title并不是指的ddd里面:title="title"title本身,他就好像是一个键值对的key一样。

而这个key所对应的值,也不是title这个具体的数据,他实际上是保存着所有ddd组件绑定的值。

所以,这个key其实是可以自定义名字的,不一定非要叫title

<template>
  <ddd v-slot:default="slotProps">
    <span>{{slotProps.title}}</span>
  </dddd>
</template>
<div>
  <span>我是子组件</span>
</div>

传递多个数据

<template>
  <div>
    <slot :title="title" test="测试数据" aaa="我是aaa"></slot>
  </div>
</template>
<template>
  <ddd v-slot:default="slotProps">
    <span>{{slotProps.title}}</span>
    <span>{{slotProps.test}}</span>
    <span>{{slotProps.aaa}}</span>
  </dddd>
</template>
<div>
  <span>我是子组件</span>
  <span>测试数据</span>
  <span>我是aaa</span>
</div>

缩写

v-slot:default="slotProps"指明这是一个默认的插槽,对于默认插槽,其实我们可以省略不写default的。

<template>
  <ddd v-slot="slotProps">
    <span>{{slotProps.title}}</span>
    <span>{{slotProps.test}}</span>
    <span>{{slotProps.aaa}}</span>
  </dddd>
</template>

但是,如果有多个插槽,比如默认插槽和具名插槽都同时存在,不管具名的插槽有没有传值,都不能使用这样的缩写,因为会导致作用域不明确。

<template>
  <ddd>
    <!--默认插槽-->
    <template v-slot:default="slotProps">
      <span>{{slotProps.title}}</span>
      <span>{{slotProps.test}}</span>
      <span>{{slotProps.aaa}}</span>
    </template>
    <!--具名插槽-->
    <template v-slot:other="otherSlotProps">
      <span>{{otherSlotProps.title}}</span>
    </template>
  </dddd>
</template>

只要出现多个插槽,请始终为所有的插槽使用完整的基于 <template> 的语法

解构插槽prop

既然插槽传过来的是一个数据的集合,是一个键值对的对象,那么我们也是可以使用解构来快速获取数据的。

<template>
  <ddd v-slot="{title,test,aaa}">
    <span>{{title}}</span>
    <span>{{test}}</span>
    <span>{{aaa}}</span>
  </dddd>
</template>

动态插槽名

动态指令参数也可以用在 v-slot 上,来定义动态的插槽名:

<base-layout>
  <template v-slot:[dynamicSlotName]>
    ...
  </template>
</base-layout>

插槽缩写补充

之前我们说了,v-slot 可以用#缩写符号代替,那么有prop传参的情况下怎么写?

<ddd>
  <template #default="{title}">
    <span>{{title}}</span>
  </template>
  <template #demo="{title}">
    <span>{{title}}</span>
  </template>
</ddd>

使用了#符号来缩写,默认插槽default就必须写上名字,不能直接#={title},这样是会报错的。

以上就是对于新版插槽的理解。

分类: vue 开发实战 标签: vueslot插槽

评论

暂无评论数据

暂无评论数据

目录