Vue Learning Notes¶
This blog records some notes when I am learning vue. The frontend framework performs quite different from the backend system which contains a lot of implicit conventions , and I try to highlight these differences to understand the vue better for frontend development.
Template Accesses Data from Component Instance¶
Template defines the page view, and it could access the data from the corresponding instance. It provides a convenient way for page rendering as you needn't replace the placeholder inside the page template after you getting data. The way of data accessing is called text interpolation. The important part to understand is the source of data, instead of template syntax which you should refer to the docs.
After knowing the template could access the data from component instance, we need to consider how to define data inside the component. Here, vue provides Composition API or Options API for you to define components, ref. They're equivalent semantically and good at solving different problems. For now, I won't continue further to differentiate them.
With Options API, we define a component's logic using an object of options such as
data
,methods
, andmounted
.
Initialization Order of Template and Component Instance¶
Knowing the template could access the data from component instance is not enough, and we need dive deeper to learn about the interaction between template and instance via renderer.
Vue provides a lifecycle diagram for reference purpose. For us, we focus on the renderer which starts to stages from the start to created
, as the below image shows:
The renderer does the following jobs:
- initializes component instance: data and hooks(such as
created
) - compiles template: the template is converted to a render function
- render: create a virtual dom by the compiled function from template
- mounting: using virtual dom as blueprint to create a real dom
If we map the jobs to the stages shown above, the job1 contains stage setup(Composition API)
and Init Options API
, job2 and job3 doesn't show in the diagram because it aims to highlight the lifecycle hooks. Then the job4 maps to the mounted
hook in the diagram.
In conclusion, vue manages a lot of work and asks developer to provide the template and instance only. It doesn't ask the developers to call a function from framework to provide his business logic. This schema confused me quite a lot because I always want to figure out the call stack relationship.
Two-Way Data Binding¶
The v-model
allows to bind variable with inputs, for example the radio button
. Here we define two ratio buttons for the same variable toggle
to make only one of them could be selected.
Two Radio Toggles
<template>
<h1>{{ toggle }} </h1>
<label>Radio Button1</label>
<input type="radio"
value="button 1"
id ="b1"
v-model="toggle"
>
<p></p>
<label>Radio Button2</label>
<input type="radio"
id ="b2"
value="button 2"
v-model="toggle"
>
</template>
<script>
import { ref } from 'vue';
export default {
data() {
return {
toggle : "Please select a button"
}
}
}
</script>
This was a bit confusing when I first learned it, so I listed all points that confused me before.
Flow of Interactivity for v-model¶
When the button is clicked, there're the following steps:
- A dom event(a signal from browser) is created
- Vue gets the dom event and update the respective data
- Vue re-renders the virtual DOM and patches the DOM
(TODO): I'm not sure when the dom event is created, the view will be updated first before vue patches the dom. I don't delve it much because it's too deep knowledge.
Why Buttons Are Exclusive¶
When I bind one variable toggle
with two radio buttons, I found vue allows me to select one button only, and will un-select the old button if I select another button.
At that time, I already know the select will update the data but have no idea that why the button is un-selected. This un-selection is actually done by the vue when it renders the dom.
First of all, v-model
finds the corresponding radio button to render via value. For example, if the value of toggle
equals button 2
, this radio button will be selected, otherwise it won't. As a result, this enables you to set the default selection among multiple radio buttons.
Because vue uses v-model
bound variable to decide whether a radio button is selected, after the data is updated and vue starts to re-render the dom, it will find the input with the same value to render the selected status.
If you two buttons share the same name with each other, they will be marked as selected together even though you only click one of them.
Browser Rendering Process¶
It's nice to learn the procedures of browser rendering, which starts from the source code, so you can understand the frontend framework better. I listed the good passages that help me to understand the procedures. The second blog introduced in more details and covered the compiling steps.
For a frontend newbie, the general procedures are: 1.parsing
-> 2. render#style
-> 3. render#layout
-> 4. render#paint
. In parsing stage, different parsers are applied to their respective contents, such as html, css and javascript. They will be parsed into the AST presentations for the further steps to process. The output of html
is so-called DOM(document object model) and the css
is CSSOM(CSS Object Model).
Parsing¶
HTML parsing usually mixes with javascript execution in a blocking mode, if the scripts are inline(not decorated by async
or defer
). For example, one stackoverflow question asked why the html parsing includes the javascript parsing.
<!-- synchronized script and will block html parsing until it's executed-->
<script src="foo.js"></script>
<!-- asynchronized script-->
<script src="foo.js" async></script>
It implies when an inline javascript is executed but the HTML parser doesn't complete to construct DOM, the javascript may fail to manipulate DOM. By this mean, the inline js usually initialization global variables, binding events or logging/debugging.
The async
script will be executed when it's ready, so it usually doesn't interact with DOM because it don't know whether DOM is fully constructed. By contrast, defer
scripts are always executed after the HTML is fully parsed so we can manipulate DOM safely.
CSSOM is parsed parallel with DOM parsing in the same process. As a result, when the defer script is executed after the DOM is constructed, CSSOM isn't guaranteed itself is ready to manipulate. By the way, the javascript runtime is maintained per page, the DOM, CSSOM and javascript runtime is 1-1 mapping.
Note the defer
execution actual is a part of rendering, but to understand the interaction between DOM and scripts, and the CSSOM, I explained here in parsing topic.
Render#Style¶
After DOM is completed to parse, the browser starts to execute defer scripts which is available to manipulate DOM. Then, it tries to create a render tree(computed style tree) by merging the DOM and CSSOM together, while the non-visual DOM elements won't be inserted in the render tree.
Layout and Painting in Render Stage¶
After getting the render tree, the browser starts to process the render tree by calculating all geolocations of all elements of render tree for the future painting. The first turn of calculation is called layout while when the render tree is changed and the calculation is triggered, it's called reflow.
Then, the GUI APIs are used to draw the UIs for the rendering tree. During re-flow, the browser optimizes a lot so only the changed parts of render tree will be re-flow and re-painted.