Vue插槽相信大家都或多或少听说过,Vue插槽官方网站如下:Vue插槽
今天系统学习了一下,作为笔记,记录下自己的理解。
1.插槽作用域
Vue中关于插槽有一条规则:父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。
这告诉我们如果想要使用到父级或者子级的作用域内的内容,需要使用特殊方法才可以访问,不能像在同一作用域内一样使用。
2.Vue插槽的几种情形
2.1 后备内容
所谓后备内容,就是替补或者default默认显示内容,比如我们在父级组件中书写了这句代码
<alertBox></alertBox>
在子组件中使用插槽写了下面这句
<div id="alertBox">
<!-- 1.插槽后备内容 -->
<slot>你好啊</slot>
<slot>你好啊</slot>
<slot>你好啊</slot>
</div>
因为父级组件中没有提供任何内容,所以slot将会显示 **你好啊**
这句话。
如果父级代码改为:
<alertBox>slot后备内容</alertBox>
显示内容将变成slot后备内容
2.2 具名插槽
这个插槽是为了个性化设计的,让用户根据需要给不同标签设计不同插槽。
比如父级代码如下:
<SpeSlot>
<template v-slot:header>
<h1>这是具名插槽</h1>
</template>
<!-- 默认具名插槽 -->
<template v-slot:default>
<p>既可以写成v-slot='default'</p>
</template>
<p>也可以不加template直接这样写</p>
<template v-slot:footer>
<p>欢迎下次光临</p>
</template>
</SpeSlot>
子组件代码如下:
<div class="box">
<div class="header">
<slot name='header'></slot>
</div>
<div class="main">
<slot></slot>
</div>
<div class="footer">
<slot name='footer'></slot>
</div>
</div>
最后都会被渲染成
<div class="box">
<div class="header">
<h1>这是具名插槽</h1>
</div>
<div class="main">
<p>既可以写成v-slot='default'</p>
</div>
<div class="footer">
<p>欢迎下次光临</p>
</div>
</div>
但是需要注意v-slot必须用在template中,还有一种特殊情况(独占默认插槽时v-slot可以不用再template中)
2.3作用域插槽
作用域插槽顾名思义是为了让数据父级组件可以替换只有插槽中才具有的数据。举个例子:
这是父级组件代码:
<RangeSlot>
<template v-slot:default='slotProps'>
{{slotProps.user.firstName}}
</template>
</RangeSlot>
其中v-slot:default=‘自定义名称’ 为获取子组件中数据,
子组件代码为:
<div class="RSlot">
<span>
<slot :user='user'>{{user.lastName}}</slot>
</span>
</div>
:user=‘user’ 自定义一个属性名用于将user进行绑定从而使父组件可以修改其数据。
最后通过以上两段代码就实现了父组件可以修改子组件中的备用数据。
2.3.1 独占默认插槽
前面说过,v-slot在此种情况下可以不必放在template中使用。
这种情况用于内容中只有默认插槽中使用。比如,
父级组件代码为:
<ORangeSlot v-slot:default='slotprops'>
{{slotprops.user.lastName}}
</ORangeSlot>
<!-- 或者 -->
<!-- <ORangeSlot v-slot='slotprops'>{{slotprops.user.lastName}}</ORangeSlot> -->
子级组件代码为:
<div class="ORSlot">
<span>
<slot :user='user'>{{user.firstName}}</slot>
</span>
</div>
但是注意不可以和具名插槽混用,以免导致作用域不明确。
2.3.2解构插槽
解构时ES2015提出的新特性,Vue插槽同样具备,你可以这样写代码来实现结构。
在上述代码中,使用的是单个参数slotprops,目前也可以写成如下形式:
<ORangeSlot v-slot='{user,animor}'>
{{user.lastName}}
{{animor.name}}
</ORangeSlot>
还可以通过{user:person,animor}进行重命名,将user改为person
<ORangeSlot v-slot='{user:person,animor}'>
{{person.lastName}}
{{animor.name}}
</ORangeSlot>
还可以通过以下方式进行定义,防止user为undefined(这种前提是没有子组件没有user对象).
<ORangeSlot v-slot="{user={age:19}}">
{{user.age}}
</ORangeSlot>
2.4动态插槽
父组件代码为:
<Vslot>
<template v-slot:[Vdata]>
<h1>动态插槽</h1>
</template>
</Vslot>
父组件数据代码为:
data(){
return{
Vdata:'header'
}
}
子组件代码为:
<div class="Vslot">
<div class="header">
<slot name='header'></slot>
</div>
</div>
2.5Vue插槽几个总结
1.v-slot和v-bind,v-on一样可以缩写为#,但是此用法只在2.6.0版本之后才可以使用。
2.父级模板里的所有内容都是在父级作用域中编译的;子模板里的所有内容都是在子作用域中编译的。