返回顶部
首页 > 资讯 > 精选 >Vue.slot原理及slot是如何实现的
  • 764
分享到

Vue.slot原理及slot是如何实现的

2023-06-30 12:06:01 764人浏览 独家记忆
摘要

本篇内容介绍了“Vue.slot原理及slot是如何实现的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、回顾 slot 用法1. 默认插

本篇内容介绍了“Vue.slot原理及slot是如何实现的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、回顾 slot 用法

1. 默认插槽

<!-- 子组件 --><template>  <div class="wrapper">    <!-- 默认插槽 -->    <div class="main">      <slot></slot>    </div></template><!-- 父组件 --><my-slot>  <template>    <h2>默认插槽</h2>  </template></my-slot>

页面展示效果如图:

Vue.slot原理及slot是如何实现的

2. 具名插槽

接着上述的案例,添加具名插槽 header ,代码如下:

<!-- 子组件 --><template>  <div class="wrapper">    <!-- header 具名插槽 -->    <header class="header">      <slot name="header"></slot>    </header>    <!-- 默认插槽 -->    <div class="main">      <slot></slot>    </div></template><!-- 父组件 --><my-slot>  <template v-slot:header>    <h2>header 具名插槽</h2>  </template>  <template>    <h2>默认插槽</h2>  </template></my-slot>

如上代码块可以发现:

  • 子组件中的 slot标签 带上了一个名为 name 的属性,值为 header

  • 父组件中的 template标签 带上了 v-slot 的属性,值为 header

页面展示效果如图:

Vue.slot原理及slot是如何实现的

3. 作用域插槽(slot-scope)

再接着上述案例,添加作用域插槽 footer ,代码如下

<!-- 子组件 --><template>  <div class="wrapper">    <!-- header 具名插槽 -->    <header class="header">      <slot name="header"></slot>    </header>    <!-- 默认插槽 -->    <div class="main">      <slot></slot>    </div>    <!-- footer 具名 + 作用域插槽 -->    <footer class="footer">      <slot name="footer" :footerInfo="footerInfo"></slot>    </footer>  </div></template><script>export default {  name: "mySlot",  data () {    return {      footerInfo: {        text: '这是 子组件 footer插槽 的作用域数据'      }    }  }}</script><!-- 父组件 --><my-slot>  <template v-slot:header>    <h2>header 具名插槽</h2>  </template>  <template>    <h2>默认插槽</h2>  </template>  <template v-slot:footer="slotProps">    <h2>footer 具名 + 作用域插槽</h2>    <p>{{ slotProps.footerInfo.text }}</p>  </template></my-slot>

如上代码块可以发现:

  • 子组件中的 slot标签 除了有 name=footer 的属性,还有一个:footerInfo="footerInfo" 的属性(作用就是传递子组件数据)

  • 父组件中的 template标签 不仅有 v-slot:footer ,并且还有一个赋值操作 ="slotProps",在模版的双括号语法中,直接通过 slotProps 访问到 子组件的 footerInfo

页面展示效果如图:

Vue.slot原理及slot是如何实现的

好了,简单回顾完用法后,笔者在这里先提三个问题:

  1. 普通插槽、 作用域插槽 的 vnode 是在哪个环节生成的,render 父组件时还是子组件时?

  2. 作用域插槽 为什么能在父组件访问到子组件的数据?

  3. 普通插槽 跟 作用域插槽 在实现上有区别吗?

我们带着疑问接着往下看!

二、不同slot的编译区别

我们根据上述最终的案例代码,执行一下打包命令,看看 Vue 在编译模板的时候,是怎么处理我们的 slot 的!事不宜迟,赶紧 build 一哈~(偷偷告诉大?,Vue 处理 作用域插槽普通插槽 的差异就是从编译开始的,也就是 render函数 会有所不同)

这里笔者顺便使用 v2.5 的具名插槽写法给大?参照一下(对具名插槽header做改写,使用 slot="header" 的写法),大家可以看下 v2.6v2.5 具名插槽的 写法、实现 上的区别~反正也不难,也就顺便带出来看看了

Vue.slot原理及slot是如何实现的

上图左边是 v2.6 、右边是 v2.5 的,这里,我们集中关注:

  • scopedSlots 属性。使用作用域插槽的 footer 的 render函数 是放在 scopedSlots 里的,并且 函数中 还有接收一个参数

  • my-slotchildren。可以发现,默认插槽的 render函数 一直都是作为当前组件的childre节点,放在 当前 组件render函数 的第三个参数

  • 关注 header 两种具名插槽写法的区别。

    • v2.6 中,我们使用了具名插槽,但是又未使用 作用域插槽的 header 被放在了 scopedSlots但是函数的参数为空,这点跟作用域插槽有区别

    • v2.5 中, 具名插槽header 仅仅作为 my-slot组件 的children节点,并且其render函数的第二个参数中有一个 slot 的属性。

其实根据上述编译后的结果,我们不妨这样猜测

  • 默认插槽直接在父组件的 render 阶段生成 vNode

    • 子组件 render 时,可能通过某种手段取得已经生成好的 插槽vNode 用作自己的 slot 节点。

    • 因为观察上述默认插槽的render函数:e("h2", [t._v("默认插槽")]),直接就是 my-slot 组件的childre节点(位于 my-slot 组件的第三个参数)。

  • 作用域插槽是在子组件 render 阶段生成 vNode

    • 因为我们观察作用域插槽 footer 的编译后结果,其不作为 my-slot 组件的 children,而是被放在了 my-slot 组件的 第二个参数 data 中的一个 scopedSlots属性里。

    • 并且,作用域插槽的 render 函数 外层的 funciton 接收了一个参数。如果在执行子组件 render 的时候调用,那完全可以拿到子组件的数据。

这里放出具体的 作用域插槽 打包后代码,大家一看就很清晰了:

{  scopedSlots: t._u([    {      key: "footer",       // 函数接收了一个参数n          fn: function (n) {        return [          // h2 标签的 render 函数          e("h2", [t._v("footer 具名 + 作用域插槽")]),           // p 标签的 render 函数,这里可以看到编译后是:n.footerInfo.text          e("p", [t._v(t._s(n.footerInfo.text))])        ]      }    }  ])}

三、slot实现原理

1. 断点调试

为了方便大家看调试结果,当前项目的组件结构主要是这样,有三大层:

Vue -> <App /> -> <my-slot />

这里笔者在运行时代码 initRender()renderSlot() 中,打上 debugger ,直接带大火看看执行流程。这里简单介绍下两个方法:

  • initRender:获取 vm.$slot 。组件初始化时执行(比如执行到 my-slot组件 时,可从vm.$slot 获取父组件中的slot vNode,也就是我们的 默认插槽)

  • renderSlot:把组件的 slot 替换成真正的 插槽vNode

接下来直接看实验截图:

先是进入initRender()(这里跳过初始化 大VueApp 的过程)。直接到初始化 my-slot组件 过程。【 简单解释:由于 App组件 执行 render 得到 App组件vNode ,在 patch 过程中 遇到 vue-component-my-slot 的 vNode ,又执行 my-slot组件 的 初始化流程。】

  • 我们不难发现,图中此时正值 my-slot组件init 阶段。

Vue.slot原理及slot是如何实现的

  • 再往下执行,我们可以得到 App组件中的 <h2>默认插槽</h2> 的vNode,赋值给 vm.$slot(这里我们记住,默认插槽的 vNode 已经得到)

Vue.slot原理及slot是如何实现的

再是进入 renderSlot()。接着上面继续单步执行,会走到 renderSlot 中。这时候,已经进入到 my-slot组件render 阶段了。回顾第一步中,此时我们手握 默认插槽的vNode,并存在 vm.$slot.default

header插槽

  • 按顺序走,先是 render 排第一的 header 的 vNode。如图所示,会走到断点处,我们接着单步

Vue.slot原理及slot是如何实现的

  • 直接进入执行我们 header插槽 的render函数执行处。根据调试步骤,我们可以肯定,放置在 scopedSlots属性 中的 render函数,是在子组件 render 的时候执行

Vue.slot原理及slot是如何实现的

  • 得到 header插槽 的 vNode

Vue.slot原理及slot是如何实现的

默认插槽

  • 继续单步走,这次轮到 默认插槽 了!如图所示,这里的 key 正是 'default'。可以发现,这里并没有像上面 header插槽 一样,去执行 render,而是直接将我们之前得到的 插槽vNode返回了。

Vue.slot原理及slot是如何实现的

  • 得到 default插槽 的 vNode

Vue.slot原理及slot是如何实现的

作用域插槽

  • 前面都跟 header插槽 一致,都是会在 my-slot 组件中 执行插槽的 render。我们直接单步到 render 处看看有什么区别。这里可以得出,function处传入的参数正是我们子组件 my-slotdata 数据,这就是为什么我们在 App组件 能通过 作用域插槽 访问到子组件数据的原因了

Vue.slot原理及slot是如何实现的

  • 最后也是返回 footer插槽 的vNode。好了,验证过程结束~

2. 总结插槽实现原理

其实上面的流程只是论证过程,大家不可以不必深陷其中。笔者在这里直接根据实践过程,给大伙总结出结论!也就是要回到我们一开始的三个问题!

普通插槽、 作用域插槽 的 vNode 是在哪个环节生成的,render 父组件时还是子组件时?

  • 默认插槽,不管 v2.5v2.6 的写法,都是在 父组件中生成 vNodevNode 存在 vm.$slot 中。待子组件 render 到插槽时,会直接拿到 父组件的 vNode

  • 具名插槽两个版本情况不一。根据编译结果可知:

    • v2.5 的写法,跟默认插槽是一样的,在父组件生成vNode,子组件直接拿来用

    • v2.6 中,直接时在 子组件 中才去执行 插槽render ,生成 插槽vNode

  • 作用域插槽。不管版本,都是在子组件中进行render的

  • 大家不妨这么理解,模版编译后,只要是被放在 scopeSlots属性 中的插槽,都会在子组件执行 render 的时候才会去生成vNode。

作用域插槽 为什么能在父组件访问到子组件的数据?

  • 作用域插槽只有子组件render的时候,才会执行render生成vNode。并且,作用域插槽的 render 函数能接参数,从而获得子组件的数据。就是这样形成了作用域插槽!所以我们能在父组件中,访问到子组件的data数据。

普通插槽 跟 作用域插槽 在实现上有区别吗?

  • 有区别。

    • 普通插槽。如果是 v2.5 ,具名插槽 和 默认插槽 都只在 父组件 render 的时候生成 vNode,子组件要 渲染slot 的时候,直接在父组件实例的 $slot 中获取已经是vNode的数据。

    • 普通插槽。如果是 v2.6 ,具名插槽 虽然是在子组件中执行的 render,但是其不接收参数

    • 作用域插槽。不管 v2.5 还是 v2.6,都只在 子组件执行 render,并且能接收参数

“Vue.slot原理及slot是如何实现的”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

--结束END--

本文标题: Vue.slot原理及slot是如何实现的

本文链接: https://lsjlt.com/news/328800.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Vue.slot原理及slot是如何实现的
    本篇内容介绍了“Vue.slot原理及slot是如何实现的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、回顾 slot 用法1. 默认插...
    99+
    2023-06-30
  • Vue3插槽Slot的实现原理是什么
    这篇文章主要介绍了Vue3插槽Slot的实现原理是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Vue3插槽Slot的实现原理是什么文章都会有所收获,下面我们一起来看看吧。Vue官方对插槽的定义Vue 实现...
    99+
    2023-07-02
  • Vue3插槽Slot实现原理详解
    目录Vue官方对插槽的定义Slot到底是什么如何使用插槽回顾组件渲染的原理插槽的初始化原理解析插槽中的内容作用域插槽原理具名插槽原理默认内容插槽的原理Vue官方对插槽的定义 Vue ...
    99+
    2024-04-02
  • spring aop底层原理及如何实现
    目录前言 使用 源码分析 总结 前言 相信每天工作都要用spring框架的大家一定使用过spring aop,aop的概念是面向切面编程,相对与传统的面向对象编程oop,aop更关...
    99+
    2024-04-02
  • 如何理解购物车原理及Java实现
    如何理解购物车原理及Java实现,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。今天来写一下关于购物车的东西, 这里首先抛出四个问题:1)用户没登陆用户名和密码,...
    99+
    2023-06-17
  • 云服务器是如何实现的原理
    云服务器是一种虚拟服务器技术,其原理是将计算资源分配给多个用户,每个用户使用自己的硬件来存储和运行应用程序。下面是云服务器实现的主要原理。 网络技术:云服务器通过网络技术连接到多个客户端和服务器,这些客户端和服务器共享计算资源。因此,云...
    99+
    2023-10-26
    如何实现 原理 服务器
  • go原子操作的方式及实现原理是什么
    今天小编给大家分享一下go原子操作的方式及实现原理是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。什么是原子操作?原子操...
    99+
    2023-07-06
  • SpringAop实现原理及代理模式是什么
    这篇文章主要介绍了SpringAop实现原理及代理模式是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇SpringAop实现原理及代理模式是什么文章都会有所收获,下面我们一起来看看吧。Spring Aop的...
    99+
    2023-06-29
  • Ajax的原理及实现过程
    这篇文章主要介绍“Ajax的原理及实现过程”,在日常操作中,相信很多人在Ajax的原理及实现过程问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Ajax的原理及实现过程”的疑惑...
    99+
    2024-04-02
  • Java优雅停机的实现及原理是什么
    这篇文章给大家介绍Java优雅停机的实现及原理是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。优雅停机 这个名词我是服的,如果抛开专业不谈,多好的名词啊!其实优雅停机,就是在要关闭服务之前,不是立马全部关停,而是做...
    99+
    2023-06-17
  • Java动态代理的原理及实现方法是什么
    本篇内容主要讲解“Java动态代理的原理及实现方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java动态代理的原理及实现方法是什么”吧!代理是指:某些场景下对象会找一个代理对象,来辅助...
    99+
    2023-07-02
  • cdn加速原理及实现方法是什么
    CDN加速原理是通过在全球分布的节点服务器上缓存静态资源,将用户请求转发至最近的缓存节点,从而提高用户访问速度和稳定性。CDN实现方...
    99+
    2023-05-30
    cdn加速原理 cdn
  • 一文了解什么是CDN及实现原理
    目录正文dns解析流程让我们来一步步分析解析流程:腾讯云cdn实例正文 由于用户访问源站业务有性能瓶颈,通过cdn技术把源站的内容缓存到多个节点。用户向源站域名发起请求时,请求会被调...
    99+
    2023-05-19
    CDN实现原理 什么是CDN
  • 理解Java注解及Spring的@Autowired是如何实现的
    首先我们可以自己写一个注解: @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @in...
    99+
    2024-04-02
  • Golang锁原理如何实现
    这篇文章主要介绍了Golang锁原理如何实现的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Golang锁原理如何实现文章都会有所收获,下面我们一起来看看吧。什么是锁锁的本质,就是一种资源,是由操作系统维护的一种...
    99+
    2023-07-05
  • Spring AOP实现原理以及如何进行CGLIB应用
    本篇文章给大家分享的是有关Spring AOP实现原理以及如何进行CGLIB应用,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。简介: AOP(Aspect Orien...
    99+
    2023-06-17
  • 云服务器是如何实现的原理和过程
    云服务器是一种虚拟服务器技术,其原理和过程与传统的服务器有很大的不同。以下是云服务器的基本原理和过程: 云计算平台的构成和运行环境:云平台通常由多个云计算服务商提供,这些服务商通过互联网连接,为用户提供云计算服务。云计算平台通常由多个虚...
    99+
    2023-10-27
    如何实现 原理 过程
  • Golangmap实践及实现原理解析
    目录Map实践以及实现原理使用实例内存模型创建maphash函数key定位和碰撞解决扩容元素访问删除迭代Map实践以及实现原理 使用实例内存模型创建maphash函数key定位和碰撞...
    99+
    2024-04-02
  • LRUCache的实现原理及利用python实现的方法
    简介 LRU(Least Recently Used)最近最少使用,最近有时间和空间最近的歧义,所以我更喜欢叫它近期最少使用算法。它的核心思想是,如果一个数据被访问过,我们有理由相信它在将来被访问的概率就越...
    99+
    2022-06-04
    原理 方法 LRUCache
  • JavaScript中Promise的原理是什么及如何使用
    这篇文章主要介绍了JavaScript中Promise的原理是什么及如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript中Promise的原理是什么及如何使用文章都会有所收获,下面我们一起...
    99+
    2023-07-05
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作