Vue.js 3 Deep Dive with Evan You - read the full article about Vue Js update, Web Development and from Vue Mastery on Qualified.One
- Welcome to the Vue 3 Deep Dive with Evan You.
This course is designed to help you learn how Vue is put together so you can more effectively build and scale your Vue applications.
Most of this course will be taught by Evan, however, there are some core concepts that you need to be familiar with in order to really understand everything that hes talking about, from the DOM to virtual DOM, to render functions to the three modules that make up the Vue core. In this video, Im going to give you a bit of an explainer so when Evan starts teaching, everything will be a little more understandable.
Well start with the basics and if this seems too simple, just stay tuned, well get to the more advanced stuff in a second.
So, first of all, what is the DOM or Document Object Model? This is our browsers interface to change what is displayed on the screen. So if we load this HTML into the browser, our browser creates these nodes, which it uses to display our webpage.
We can change its text content to "New Heading", which updates the node and then updates our browser.
Webpages can have a lot of DOM nodes, which means DOM trees can have thousands of nodes.
However, searching and updating thousands of DOM nodes can obviously get slow.
This is why Vue and other frameworks like it have something called the virtual DOM.
For example, this HTML can also be represented by a virtual node, which looks like this.
Vue knows how to take this virtual node and mount it onto the DOM, which updates what we see in our browser.
Theres actually another step in here where Vue creates a render function based on our template, which returns a virtual DOM node.
Render functions can look something like this.
When a component changes, the render function gets rerun, which creates another virtual node.
We then send the old V node and the new V node into Vue to compare the two and make updates in the most efficient way onto our webpage.
An effective way of thinking about the virtual DOM versus the actual DOM are the blueprints and the actual building.
Lets say Ive changed some data on the 29th floor.
Ive changed the layout of my furniture and added some kitchen cabinets.
There are two ways I can make these changes. First, I can demolish everything on the 29th floor and rebuild it from scratch, or I can create new blueprints, compare the old and the new blueprints and make updates to do the minimal amount of work.
This is kind of how the virtual Dom works and Vue 3 has become even more efficient at making these updates quickly, which is something youre going to learn all about in this course. Vue has three core modules.
Theres the reactivity module, the compiler module, and the renderer module.
Lets go through them one at a time.
When code which uses these objects are run, theyre tracked so they can be run later if the reactive object changes.
I just finished creating an entire course on Vue 3 reactivity, which I highly recommend you take.
If you take it before this course, things will be a lot more understandable when we get to the reactive part.
Next is the compiler module.
This knows how to take HTML templates and compile them into render functions.
This can happen in the browser runtime, but more often happens when a Vue project is built, so that a browser only ever receives render functions.
Finally, the renderer module contains code for three different phases of rendering out a component onto a webpage.
Theres the render phase, the mount phase and the patch phase.
In the render phase, the render function is called and it returns a virtual DOM node.
There you have it, the three modules of Vue core.
Now lets dive into an example and look at the execution of a simple component.
So here you can see my simple component and it has a template, and a reactive object which is used inside the template.
First, the template compiler changes the HTML into a render function.
Then, the reactive objects are initialized using the reactivity module. Next, inside the renderer module, we enter the render phase, this invokes the render function, which references the reactive object.
We now watch this reactive object for changes and the render function returns a virtual DOM node.
Next in the mount phase, the mount function is called using the virtual DOM node to create the webpage.
Lastly, if any changes happen to our reactive object, which is being watched, the renderer invokes the render function, again, creating a new virtual DOM node, both the new and the old virtual DOM node get sent in to the patch function, which then makes updates to our webpage as needed.
Okay. With this information, it should be a lot easier to get through the information that Evans going to throw at you in the next few lessons.
Hope you enjoy it.
- There are some benefits of having a virtual DOM layer, the most important one is that it completely decouples your component rendering logic from the actual DOM and makes it more straightforward to reuse the runtime of a framework in other environments.
For example, Vue allows third party developers to create customized rendering solutions that targets not just the browser, but also native environments like iOS and Android.
It is also possible to use the API to create a custom renderer that directly renders to WebGL instead of DOM nodes. So in Vue 2, we in fact already have this capability. However, the API we provided in Vue 2 was not officially documented and required forking our source code in order to maintain it.
So that places a lot of maintenance burden on the developers developing these custom solutions. In V3, we are making the custom renderer API a first-class API so developers can directly pull in Vue runtime core as a dependency, and then leverage the custom renderer API to build their own custom renderer. In fact, we already have early users reporting that theyve successfully built a web GL renderer using the V3 API.
Another important aspect about virtual DOM is it provides the ability to programmatically construct, inspect, clone, and manipulate the desired DOM structure before actually returning it to the rendering engine.
Now, this ability is important because there will eventually be certain cases in UI programming where the template syntax will be somewhat limiting and you just need to have the full flexibility of a proper programming language to express the underlying logic. Now such cases is in fact, pretty rare in day-to-day UI development.
It happens more often when you are authoring a library or authoring a UI component suite that you intend to ship to be used by third-party developers.
Lets imagine components like a complex type of head box or an input box associated with a bunch of tasks.
These types of components typically contain very little markup, but they will contain a lot of interactive logic.
And in those cases, the template syntax sometimes will actually restrict you from expressing the underlying logic easier.
- So what Im getting from you is that templates will get you where you want to go in just writing out the HTML like 99% of the time, but every once in a while, you might want to do something more programmatically and in that case, you want to code up a render function.
And what does a render function look like? - So a render function in Vue 2 looks like this.
So this is an option in your component definition.
Instead of providing a template option, you can give your component a render function instead.
In Vue two, you will receive the H argument that we talked about earlier directly as an argument to the render function.
And you can use that to create what we call virtual DOM nodes or V nodes for short.
A V node takes the first argument is the type.
So here we have creating a div.
The second argument is an object containing all the data or props on the V node. In V2, the API is a little bit verbose in the sense that you have to be specific about what type of binding youre passing to the node. For example, if you want to bind an attribute, you have to nest it under the ATTRS object, and if you want to bind an event listener, you have to nest it under on.
And the third argument is the child nodes of this V node.
So directly passing the string is a convenient API for you to say, this node only contains text children, but it can also be an array that contains more child nodes.
So you can, you can have an array here and nest it with more nested H calls.
Now we changed the API with the goal of simplifying it in Vue 3. The first note about change is we now have a flat prop structure in the sense when you call H, the second argument now is always a flat object and you can directly pass an attribute to it.
Here we are just giving it an ID.
And event listeners by convention will start with on.
So anything with on would automatically be bound as an event listener.
So you dont have to think about the nesting that much.
In most cases, you also dont need to think about whether this should be bound as an attribute or a DOM property, because Vue will intelligently figure out the best way to do it for you.
We in fact check whether this key exists on the native DOM node as a property, and if there is a property, well set it as a property. If it doesnt exist, well just set it as an attribute.
And it has been working out well so far in practice.
- I know that the original sort of virtual DOM implementation, you took inspiration from other projects. Is that correct? - Yes. There was a library called Snabbdom, which Vue 2s Virtual DOM was essentially forked from that.
- Okay. And then Vue 3, the way you coded it here, is this just improving upon the patterns? - Well, Vue 3 was kind of a complete rewrite.
So pretty much from the ground up, everything is just custom.
Obviously there are existing algorithms or like no diffing cause these are areas that weve seen the community doing extensive research on.
So if this is built upon knowledge of all these previous implementations, but the code itself is now written from the ground up.
- Wow. And thats all in TypeScript, right? - Yes. All in TypeScript.
Another change about the render function API is the H helper is now globally imported directly from Vue itself.
This change mainly comes from the frustration from some users when in Vue 2, because the H is past here and in fact this H is special because its bound to the current component instance.
So when you want to split a large render function into smaller ones, you actually have to pass this H all the way through these split functions.
So that kind of makes it a bit difficult to... its just a little annoyance, but with a globally imported H, you can import it once and you can split your render function into as many ones as you want in the same file without having to think about it.
- Oh, I see the render function doesnt have an argument.
- Right. Well internally, it does receive arguments, but thats used only by the compiler generated code.
When users use it directly, they always just grab stuff off of this.
So if you use the TypeScript with a defined component API, youll get full type inference on this as well.
Vue Mastery: Vue.js 3 Deep Dive with Evan You - Web Development