Nano_Vue2 aims to further understand the inner workings of Vue2
- global API:
- NanoVue.mixin
- NanoVue.component
- NanoVue.extend
- options / Data:
- data
- watch
- computed
- methods
- options / DOM:
- el
- template
- render
- options / Lifecycle Hook:
- beforeMount
- mounted (only root instance)
- instance property:
- $data
- $options
- $el
- instance method / data:
- $watch
- $set
- instance method / lifecycle:
- instance.$mount
- instance.$nextTick
- directives:
- v-for
- v-if
- v-on
Template String
(👇parse👇)
Abstract Struct Tree
(👇generate👇)
Render Function
(👇invoke👇)
Virtual DOM
(👇patch👇)
DOM
In Vue2, converting HTML to AST uses regular expressions.
In Vue3, this step is implemented by implementing a finite state machine according to the WhatWG specification. In fact, the bottom layer of regularity can also be understood as a finite state machine.
Vue 3 Initial Flow:
Template String
(👇parse👇)
Abstract Struct Tree
(👇generate👇)
AST for RenderFunction
(👇transform👇)
Render Function
(👇invoke👇)
Virtual DOM
(👇patch👇)
DOM
You will find that there are more steps. This is because Vue2’s approach is a bit tricky! More details are implemented in Vue3, making the architecture more flexible.
Vue3 implements a finite state machine to parse the template to generate Tokens, generate AST through Tokens, and then traverse the AST to generate the AST that can construct the rendering function.
Reactive = Observer pattern + Object.defineProperty
Observer pattern = Watcher(Observer) + Dep(observale object)
The principle of SSR in Vue2 is actually similar to CSR. The similarities are that the template is parsed and lexically analyzed on the server side, and then converted into a rendering function. Then the HTML string is concatenated according to the rendering function.
Currently, the functions that have been implemented are:
const render = createRenderer();
render.renderToString(app, (err, res) => {});
However, HTML templates are not supported. In addition, I directly used the CSR compiler, many directives were not compatible, and a large part of the magic was modified. In Vue SSR, there is actually a similar compiler to be compatible with the server-side scenario. Currently, it can only convert HTML tags and strings. Component level is not implemented yet.
Currently, NanoVue2 has implemented some hydration capabilities (only supports simple elements). The core of this part is:
- When
$mount
, it will obtain whether there is a server-rendered tag on the target mounted DOM:data-server-rendered='true'
, and hydrate if it exists. - During the hydration process, since the client will also execute code similar to
new NanoVue()
, a virtual DOM tree has been generated according to the template.hydrate
after$mount
will match the virtual DOM tree with the real DOM tree one by one to determine whether the hydration is successful
Demo: Server Rendered HTML
<div data-server-rendered="true" id="app"><div id="foo">1</div></div>
Client Side Script
const instance = new NanoVue({
template: `<div id="app"><div id="foo" @click="handleClick">{{count}}</div></div>`,
data: {
count: 1,
},
methods: {
handleClick() {
this.count++;
},
},
});
instance.$mount("#app");
- WeChat:ys5-14
- Email: [email protected]