关于插槽Slot

本文介绍了Vue.js中的插槽概念,包括默认插槽、具名插槽和作用域插槽,强调了插槽如何实现父组件内容在子组件中展示,以及作用域的问题。作用域插槽允许父组件访问子组件的数据,解决了内容编译作用域的限制。此外,还提到了已被废弃但仍在某些库中使用的`slot-scope`特性。

前言

城建实习的时候,有用到过几次作用域插槽,之前看课的时候算是一知半解,看自己记得笔记也挺多疑惑,这里就再重新整理一下吧。

插槽的作用:父组件的内容可以在子组件内展示,即父传子

一、默认插槽

/* 父组件 标签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>

比如上述代码,接收了那一行的数据,传递给了插槽(子组件),然后里面就可以用各种数据(而且不加这个插槽还会出问题,渲染的时候会达不到自己想要的效果。)

插槽slot)是一种在组件化开发中非常有用的特性,主要用于实现组件的内容分发和复用,使组件更加灵活和可定制。以下从几个方面详细介绍其作用: - **内容分发**:在组件化开发中,组件可能需要在不同的使用场景下展示不同的内容。插槽允许将父组件中的内容插入到子组件的指定位置,实现内容的分发。例如,在一个`Category`组件中定义了一个插槽,当使用者没有传递具体结构时,会显示默认内容;当传递了具体结构时,会显示传递的内容。 ```vue <template> <div class="category"> <h3>{{title}}分类</h3> <slot>我是一些默认值,当使用者没有传递具体结构时,我会出现</slot> </div> </template> <script> export default { name: 'Category', props: ['title'] } </script> <style scoped> .category { background-color: skyblue; width: 200px; height: 200px; } h3 { text-align: center; background-color: orange; } video { width: 100%; } img { width: 100%; } </style> ``` - **实现具名插槽**:当组件需要多个插槽时,可以使用具名插槽。具名插槽允许在子组件中定义多个不同名称的插槽,父组件可以根据插槽名称将内容插入到相应的位置。例如,在子组件中定义了一个具名插槽`header`,父组件可以通过`v-slot`指令将内容插入到该插槽中。 ```vue // Child.vue <template> <div> <!-- 具名插槽 --> <div> <slot name="header"> <h3>没传header插槽</h3> </slot> </div> </div> </template> <style scoped> div { border: 1px solid #000; } </style> // Parent.vue <child> <!-- 具名插槽 --> <template v-slot:header>具名插槽header</template> <!-- 具名插槽 v-slot也有缩写,可用#name表示 --> <template #header>具名插槽header</template> </child> ``` - **实现作用域插槽**:作用域插槽允许子组件将数据传递到父组件中的插槽内容中,使得父组件可以使用子组件中的数据进行渲染。本质上会把父组件的内容渲染成函数,子组件调用函数,并且将数据传递给它,函数的返回值就会替换掉这个占位符。在 Vue 2 中,作用域插槽通过`<slot>`元素的`name`属性以及`<template slot-scope="props">`来实现;在 Vue 3 中,作用域插槽的语法发生了变化,使用`v-slot`指令和新的`#`符号来指定插槽的作用域[^3]。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值