Home>Article>Web Front-end> Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

青灯夜游
青灯夜游 forward
2022-05-10 11:55:03 2867browse

This article will share with youVuedry information and talk about the principles of Vue.slot that you may not know. I hope it will be helpful to everyone!

Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

I believe that whether it is daily business development or encapsulation of basic components,slot slotoften appears in our field of vision, because It provides a lot of convenience for our programming implementation. Maybe everyone is familiar with the usage ofslot, whether it isnamed slot, orscope slotvarious usages, etc... Do you know how the bottom layer ofslotandslot-scopeis implemented?

Easy to understand,You can take away'sVue.slotin 10 minutesSource code implementation analysis! ! ! Follow the author to explore how the slotslotinVue (v2.6.14)is implemented! ! This article will mainly explain it in two parts:

  • Normal slots (named slots, default slots)

  • Scope slot

This article does not have obscure source code analysis, it is explained directly in vernacular, so no matter how familiar you are with the Vue source code, you can understand it. Through on-site debugging, you can see clearly how theslotofVueis implemented. let's go go go! (Learning video sharing:vue video tutorial)

1. ReviewslotUsage

Let me first review the general usage of the slot. The usage ofslothere uses the new standard of2.6.0(this article will also explain how to writev2.5andv2.6What is the difference in source code implementation!).

If you want to learn more about usage, you can go to the official website to read Vue’s slot documentation in detail

https://cn.vuejs.org/v2/guide/components-slots.html

1. Default slot

     

The page display effect is as shown in the figure:

Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

2. Named slot

Follow the above case, add a named slotheader, the code is as follows:

      

The above code block can be found:

  • in the subcomponent Theslot tagcarries an attribute namedname, and the value isheader

  • in the parent component Thetemplate taghas the attributev-slot, and the value isheader

The page display effect is as follows:

Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

3. Scope slot (slot-scope)

Following the above case, add the scope slotfooter, The code is as follows

        

The above code block can be found:

  • Theslot tagin the subcomponent except forname=footerAttribute, there is also a:footerInfo="footerInfo"attribute (its function is to pass the child component data)

  • template tag in the parent componentNot only hasv-slot:footer, but also has an assignment operation="slotProps". In the double bracket syntax of the template, directly passslotPropsAfter accessing thefooterInfo

# page of the sub-component, the page display effect is as shown in the figure:

Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

Okay, a brief review After finishing the usage, the author will ask three questions here:

  1. At what stage are the vNodes of ordinary slots and scope slots generated? When rendering the parent component or the child component?
  2. Scope Slot Why can the data of child components be accessed from the parent component?
  3. Is there any difference in implementation between ordinary slots and scope slots?

Let’s read on with questions!

2. Differences in compilation of differentslot

Based on the final case code above, we execute the packaging command to see how Vue handles it when compiling the template. Ourslot's! Without further ado, hurry up andbuild~ (Secretly tell everyone,Vuehandlesscope slotsandnormal slotsThe difference starts from compilation, that is, the render function will be different)

Here I will use the named slot writing method ofv2.5to give you a reference (for named slots To rewrite the header, useslot="header"), you can take a look at the writing and implementation ofv2.6,v2.5The difference~ It’s not difficult anyway, so I took it out to have a look

Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

上图左边是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("h1", [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 [ // h1 标签的 render 函数 e("h1", [t._v("footer 具名 + 作用域插槽")]), // p 标签的 render 函数,这里可以看到编译后是:n.footerInfo.text e("p", [t._v(t._s(n.footerInfo.text))]) ] } } ]) }

三、slot实现原理

1. 断点调试

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

Vue->->

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

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

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

接下来直接看实验截图:

1、先是进入initRender()(这里跳过初始化大VueApp的过程)。直接到初始化my-slot组件过程。【 简单解释:由于App组件执行render得到App组件vNode,在patch过程中 遇到vue-component-my-slot的 vNode ,又执行my-slot组件的 初始化流程。不是很熟悉组件化流程的朋友可以去看看笔者的Vue响应式原理~】

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

Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

  • 再往下执行,我们可以得到 App组件中的

    默认插槽

    的vNode,赋值给vm.$slot(这里我们记住,默认插槽的 vNode 已经得到)

Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

2. Then enterrenderSlot(). Then continue the single-step execution above and you will reachrenderSlot. At this time, we have entered therenderstage ofmy-slot component. Looking back at the first step, at this time we have the vNodeof thedefault slot, and there is the

header slot in

vm.$slot.default

  • Go in order, first render the vNode of the first ranked header. As shown in the figure, we will reach the breakpoint, and we will then step

Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

  • directly into the execution of the render function of our header slot. According to the debugging steps,we can be sure that the render function placed in thescopedSlots attributeis executed when the subcomponent renders

Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

  • Get the vNode of the header slot

Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

##Default slot

    Continuing the single step, this time it’s the default slot’s turn! As shown in the picture, the
  • keyhere is exactly'default'. It can be found thatdoes not execute render like the header slot above, but directly returns the slot vNode we got before.

Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

    Get the vNode of the default slot

1Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

Scope slot

    The front is the same as the header slot, and the render of the slot will be executed in the my-slot component. Let’s step directly to render to see what the difference is. It can be concluded here that the parameters passed in at
  • function are exactly thedatadata of our sub-componentmy-slot, which is why we useApp componentThe reason why sub-component data can be accessed throughscope slot

1Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!

  • Finally also Returns the vNode of the footer slot. Okay, the verification process is over~

2. Summarize the slot implementation principle

In fact, the above process is just a demonstration process, and you don’t have to get stuck in it. The author here directly summarizes the conclusion for everyone based on the practical process! That is to say, we have to go back to the three questions we asked at the beginning!

1. At which stage are the vNodes of ordinary slots and scope slots generated? When rendering the parent component or the child component?

  • Default slot, regardless of howv2.5andv2.6are written, are in the parent componentvNodeis generated in .vNodeexists invm.$slot. When the child componentrenderreaches the slot,will directly get thevNode

  • of the parent component. Named SlotThe situation is different between the two versions. According to the compilation results, it can be seen that:

    • v2.5is written in the same way as the default slot. vNode is generated in the parent component and used directly by the child component

    • v2.6,slot renderis executed directly in the sub-component to generateslot vNode.

  • Scope slot. Regardless of the version,is rendered in the subcomponent.

  • You may wish to understand it this way. After the template is compiled, as long as it is a slot placed in the

    scopeSlots attribute, it will not be used until the subcomponent executes render. Generate vNode.

2. Scope slot Why can the data of child components be accessed from the parent component?

    Scope slot
  • Only when the subcomponent is rendered, the render will be executed to generate vNode. Moreover, the render functionof the scope slot can receive parameters to obtain the dataof the subcomponent. This is how scope slots are formed! So we can access the data of the child component in the parent component.
3. Is there any difference in implementation between ordinary slots and scope slots?

    There is a difference.
    • Normal Slot. If it isv2.5, both the named slot and the default slot will only generate vNode when the parent component renders. When the child component wants to render the slot, it will be directly obtained from the $slot of the parent component instance. vNode data.

    • Normal Slot. If it isv2.6, although the named slot executes render in the child component,it does not receive parameters.

    • Scope slot.Regardless ofv2.5orv2.6, render will only be executed in the subcomponent and can receive parameters.

Okay, let’s give a concise summary at the end.The scope slot must be delayed and receive parameters! Ordinary slots may be executed delayed or directly, but do not receive parameters!


Written at the end, many times we copy bricks and follow the documentation to implement the functions, which is really labor-saving and worry-free~ But if you do it too much, you will find that the current things lack challenges and are boring. . At this time, there will be an impulse to delve into its implementation principle and see howslotis implemented. Especiallyscope slots. When using it, you will take it for granted that the upper-level component should obtain the data of the sub-component through the scope slot. However, after digging into the source code and understanding how others do it, you will suddenly feel enlightened~

(Learning video sharing:web front-end development,Basic programming video)

The above is the detailed content of Let’s talk about the principle of Vue.slot and let’s explore how slot is implemented!. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete