Skip to content

Nano_Vue2 aims to further understand the inner workings of Vue2

Notifications You must be signed in to change notification settings

Mori-Young/Nano_Vue2

Repository files navigation

Nano_Vue2

Nano_Vue2 aims to further understand the inner workings of Vue2

logo

Implemented Features

  • 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

Initial Flow

Template String
(👇parse👇)
              Abstract Struct Tree
                (👇generate👇)
                                   Render Function
                                    (👇invoke👇)
                                                   Virtual DOM
                                                   (👇patch👇)
                                                                DOM

vs. Vue3

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

Reactive = Observer pattern + Object.defineProperty

Observer pattern = Watcher(Observer) + Dep(observale object)

SSR

Server side

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.

Client Side

Currently, NanoVue2 has implemented some hydration capabilities (only supports simple elements). The core of this part is:

  1. 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.
  2. 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");

Contact me

About

Nano_Vue2 aims to further understand the inner workings of Vue2

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published