深入解释 Vue 插槽的作用和原理
前言
在2.6.0中,具名插槽 和 作用域插槽 引入了一个新的统一的语法 (即v-slot 指令)。它取代了 slot 和 slot-scope。
什么是Slot
当我们生成好组件模板后,为了方便用户在调用组件的时候自定义组件内部分元素的样式或内容。于是在设计组件模板的时候会挖一个坑,等待用户使用v-slot来替换坑的slot位置。
栗子
// father.vue <template> <div> <child> <h1>AAAA</h1> </child> </div> </template>
<template> <div> <p>这里是子组件哦</p> <slot></slot> </div> </template>
可以看见 <h1>AAAA</h1>被 插入到child的里面。
除了可以插入HTML模板代码外,你也可以插入普通文本、其他组件、本组件的数据。
在插槽中使用数据
// father.vue <template> <div> <child> {{testName}} <h1>AAAA</h1> </child> </div> </template> <script> ... testName = 'Test101'; ... </script>
插槽可以使用当前引用子组件的组件数据,但是不能引用传递给子组件的数据。
// father.vue <template> <div> <child :childName="testName"> {{ childName }} <h1>AAAA</h1> </child> </div> </template> <script> ... testName = 'Test101'; ... </script>
// child.vue <template> <div> <p>这里是子组件{{ childName }}</p> <slot></slot> </div> </template> <script> import { Component, Vue, Prop } from 'vue-property-decorator'; @Component() export default class AAChild extends Vue { @Prop() childName; } </script>
这里是获取不到childName的,因为这个值是传给<child>的
备胎插槽
// father.vue <div> <child :childName="testName"> </child> </div>
// child.vue <div> <p>这里是子组件{{ childName }}</p> <slot> 我是备胎 </slot> </div>
给插槽设置一个具体的默认内容,当别的组件没有给你内容的时候,那么默认的内容就会被渲染。如果我们提供内容,那么默认的插槽内容会被我们的内容覆盖。
具名插槽
当我们一个组件里需要定义多个插槽时,需要使用slot元素的特性name来定义额外的插槽。
// child.vue <template> <div> <p>插槽一的位置</p> <slot name="slot1"> </slot> <p>------------------------</p> <p>插槽二的位置</p> <slot> </slot> <p>------------------------</p> <p>插槽三的位置</p> <slot name="slot3"> </slot> </div> </template>
// father.vue <child> <template v-slot:slot1> <h1>slotOne</h1> </template> <template> <h1>slotTwo</h1> </template> <template v-slot:slot3> <h1>slotThree</h1> </template> </child>
如果一个<slot>不带name属性的话,那么它的name默认为default,可以不用v-slot去指定它。(如果你非要折腾,也可以写name="default")
在向具名插槽提供内容的时候,我们可以在<template>元素上使用v-slot指令,并以参数的形式提供其名称。
注:v-slot只能添加在一个<template>上,(只有一种例外情况,下面会说)
覆盖问题
当存在同名的v-slot的时候,后面会覆盖前面的。
当存在两个匿名的插槽的时候,两者都会被丢进去默认插槽里。
只更改了father.vue
// father.vue <child> <template v-slot:slot1> <h1>slotOne</h1> </template> <template> <h1>slotTwo</h1> </template> <template v-slot:slot3> <h1>slotThree</h1> </template> <template v-slot:slot3> <h1>slotThreeAAAAAAAAA</h1> </template> <template> <h1>slotTwoAAAAAAAAAAAA</h1> </template> </child>
作用域插槽
插槽跟模板其他地方一样都可以访问当前father组件的作用域而不能访问<child>的作用域
如果要访问child的作用域该怎么办呢?
// child.vue <template> <div> <p>下面有一个插槽</p> <slot :aName="name"></slot> </div> </template> <script> import { Component, Vue, Prop } from 'vue-property-decorator'; @Component() export default class AAChild extends Vue { name = '123'; } </script>
// father.vue <template> <div> <child> <template v-slot:default="slotProps"> <h1>{{ slotProps.aName }}</h1> </template> </child> </div> </template>
v-slot:default="slotProps"接住了child组件里在slot元素上绑定的作用域属性,同时吧template只想了默认插槽。
具名插槽的作用域
// father.vue <template> <div> <child> <template v-slot:default="slotProps"> <h1>{{ slotProps.aName }}</h1> </template> <template v-slot:slotA="slotProps"> <h1>{{ slotProps.nameA }}</h1> </template> </child> </div> </template>
// child.vue <template> <div> <p>下面有一个插槽</p> <slot :aName="name"></slot> <slot :nameA="nameA" name="slotA"></slot> </div> </template> <script> import { Component, Vue, Prop } from 'vue-property-decorator'; @Component() export default class AAChild extends Vue { name = '123'; nameA = '321'; } </script>
过时的写法:
<template slot="custom" slot-scope="item"></template >
现在的写法:
<template v-slot:custom="{item}"></template >
解构插槽Prop
v-slot 的值实际上可以是任何能够作为函数定义中的参数的 JS 表达式(作用域插槽 的内部工作原理是将你的插槽内容包括在一个传入单个参数的函数里)
// child.vue <template> <div> <p>下面有一个插槽</p> <slot :nameData="nameObj"></slot> </div> </template> <script> import { Component, Vue, Prop } from 'vue-property-decorator'; @Component() export default class AAChild extends Vue { nameObj = { name: '插槽君', key: '202203241567', }; } </script>
// father.vue <template> <div> <child> <template v-slot="slotProps"> <h1>{{ slotProps.nameData.name }}</h1> </template> </child> </div> </template>
father,vue可以改写为
// father.vue <template> <div> <child> <template v-slot="{ nameData }"> <h1>{{ nameData.name }}</h1> </template> </child> </div> </template>
这样可以使模板更简洁。
具名插槽的缩写
跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。例如 v-slot:header 可以被重写为 #header:
// father.vue <template> <div> <child> <template v-slot:keyDDD="{ nameData }"> <h1>{{ nameData.name }}</h1> </template> </child> </div> </template>
等同于
// father.vue <template> <div> <child> <template #keyDDD="{ nameData }"> <h1>{{ nameData.name }}</h1> </template> </child> </div> </template>
$scopedSlots
和slot-scope 的区别?
- 作用相同:都是作用域插槽
- 场景不同:slot-scope 是模板语法,scopedSlots 则是编程式语法
- 使用不同:在 <template> 中使用 slot-scope,在 render() 函数中使用 scopedSlots
<template v-if="$scopedSlots.label" v-slot:title="{ data }"> <slot name="label" :data="data" > </slot> </template>
或者
render() { return this.$scopedSlots.default ? this.$scopedSlots.default(this.title) : null; }
到此这篇关于Vue slot插槽作用与原理深入讲解的文章就介绍到这了,更多相关Vue slot插槽内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
下一篇: Vue3 插槽(槽位)使用详情
推荐阅读
-
玩转Vue:匿名、具名和作用域插槽的运用指南
-
深入解析MySQL的锁机制:探索S锁、X锁和意向锁的作用与原理
-
深入理解 Vue 中的 KeepAlive:原理和源码解析
-
【2022新手指南】Java编程进阶之路 - 六、技术架构篇 ### MySQL索引底层解析与优化实战 - 你会讲解MySQL索引的数据结构吗?性能调优技巧知多少? - Redis深度揭秘:你知道多少?从基础到哨兵、主从复制全梳理 - Redis持久化及哨兵模式详解,还有集群搭建和Leader选举黑箱打开 - Zookeeper是个啥?特性和应用场景大公开 - ZooKeeper集群搭建攻略及 Leader选举、读写一致性、共享锁实现细节 - 探究ZooKeeper中的Leader选举机制及其在分布式环境中的作用 - Zab协议深入剖析:原理、功能与在Zookeeper中的核心地位 - RabbitMQ全方位解读:工作模式、消费限流、可靠投递与配置策略 - 设计者视角:RabbitMQ过期时间、死信队列与延时队列实践指南 - RocketMQ特性和应用场景揭示:理解其精髓与差异化优势 - Kafka详细介绍:特性及广泛应用于实时数据处理的场景解析 - ElasticSearch实力揭秘:特性概述与作为搜索引擎的广泛应用 - MongoDB认知升级:非关系型数据库的优势阐述,安装与使用实战教学 - BIO/NIO/AIO网络模型对比:掌握它们的区别与在网络编程中的实际应用 - Netty带你飞:理解其超快速度背后的秘密,包括线程模型分析 - 网络通信黑科技:Netty编解码原理与常用编解码器的应用,Protostuff实战演示 - 解密Netty粘包与拆包现象,怎样有效应对这一常见问题 - 自定义Netty心跳检测机制,轻松调整检测间隔时间的艺术 - Dubbo轻骑兵介绍:核心特性概览,服务降级实战与其实现益处 - Dubbo三大神器解读:本地存根与本地伪装的实战运用与优势呈现 ----------------------- 七、结语与回顾
-
其主要作用是实现组件的重用和封装,使组件更具灵活性和可定制性。具体来说,可以在组件内部注入插槽来实现动态渲染,同时还能保留组件的固有结构和风格。槽的优点是使组件更加灵活,通过槽可以传递不同类型的数据,实现不同的表达形式。缺点是使用插槽会导致代码可读性差,同时也会增加实现成本。 本文主要介绍 Vue3 插槽 slot 的使用。 I.默认槽 示例代码:
-
了解 Vue 中的插槽 - 注意:当父组件使用子组件时,插槽和命名插槽不能嵌套,这会导致作用域不清晰。
-
深入解释 Vue 插槽的作用和原理
-
Vue 中插槽的作用和细节原则
-
Vue 中的插槽用法:默认槽、命名槽和作用域槽
-
深入了解数据验证(Bean Validation):由浅入深地掌握 @Valid 的作用(级联验证)和常用的注释解释约束 [尽情学习 Java] (下)