前言
城建实习的时候,有用到过几次作用域插槽,之前看课的时候算是一知半解,看自己记得笔记也挺多疑惑,这里就再重新整理一下吧。
插槽的作用:父组件的内容可以在子组件内展示,即父传子
一、默认插槽
/* 父组件 标签navigation-link为子组件的名字 标签内内容为要传过去的值*/
<navigation-link url="/profile">
wanwan
</navigation-link>
/*子组件 即navigation-link组件*/
<div>
<slot></slot>
</div>
当组件渲染的时候,子组件 将会被替换为“wanwan”,实现父组件的内容在子组件里展示。
**注意:**插槽的作用域问题是需要考虑的,比如,父组件中的url属性,在子组件内是得不到的
/* {url}为undefined*/
<navigation-link url="/profile">
wanwan{{url}}
</navigation-link>
官网解释: 该插槽跟模板的其它地方一样可以访问相同的实例 property (也就是相同的“作用域”),而不能访问 的作用域。例如 url 是访问不到的
「父级模板」里的所有内容都是在「父级作用域」中编译的;「子模板」里的所有内容都是在「子作用域」中编译的。
二、具名插槽
具名插槽的主要功能是:解决需要同时用多个插槽的情况。
<!-- 父组件 slot有两种写法 slot="xxx"和v-slot:xxx -->
<Category>
<header slot="header">
<!-- 我们希望把页头放这里 -->
</header>
<main>
<!-- 我们希望把主要内容放这里 -->
</main>
<footer v-slot:footer>
<!-- 我们希望把页脚放这里 -->
</footer>
<Category/>
<!-- 子组件Category -->
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
PS:这样就能实现一个萝卜一个坑了,其中一个不带 name 的 出口会带有隐含的名字**“default”**。
三、作用域插槽
这也是最近用的最多的吧,elementUI里面也会用到,公司的代码里也有好几处都有。
首先还是要理解上面所说的那句话:
「父级模板」里的所有内容都是在「父级作用域」中编译的;「子模板」里的所有内容都是在「子作用域」中编译的。
想让插槽内容(父组件)能够访问子组件中才有的数据,前两种插槽是无法实现的,因为父级模板里面没有子组件内的数据,直接用会返回undefined。
解决方法就是作用域插槽
(这边先写最简单的,具名插槽和作用域不混用的简写情况,将来若有别的需求则看链接: 官网-slot)
/*子组件 绑定一个数据,传给父组件,「v-bind:」可简写为 「:」*/
<span>
<slot v-bind:user="user">
{{ user.lastName }}
</slot>
</span>
/*父组件,slotProps是自定义名字,可以改成别的*/
<current-user v-slot="slotProps">
{{ slotProps.user.firstName }}
</current-user>
**官网提示:**只要出现多个插槽,请始终为所有的插槽使用完整的基于 的语法:
<current-user>
<template v-slot:default="slotProps">
{{ slotProps.user.firstName }}
</template>
<template v-slot:other="otherSlotProps">
...
</template>
</current-user>
slot-scoped
这个在2.6.0之后就被废弃了,但是现在还能用,而且像ElementUI也还在用,还是需要学习一下的,知其然且知其所以然嘛。
“在template标签使用特殊的 slot-scope attribute,可以接收传递给插槽的 prop ”
<template slot-scope="{row}">
<el-select v-model="row.type" placeholder="请选择">
<el-option v-for="item in picTypeSelectOption" :key="item.value" :label="item.label" :value="item.value"></el-option>
</el-select>
</template>
比如上述代码,接收了那一行的数据,传递给了插槽(子组件),然后里面就可以用各种数据(而且不加这个插槽还会出问题,渲染的时候会达不到自己想要的效果。)