Simple implementation method of vue3 source code analysis

Simple implementation method of vue3 source code analysis

Preface

Recently, my first official vue3 + ts project has entered the acceptance stage. Hearing you guys talking about vue3, vue3 all the time, I wanted to see what the difference is between vue3 and vue2. 🤷🏻‍♀️🤷🏻‍♀️🤷🏻‍♀️

This article mainly explains the API usage of vue3 and simply implements a vue3. Let me show you the difference between vue3 and the previous vue2. And briefly reveal the process of vue3 initialization in the source code.

🍹Preparation

If you want to see how the source code inside vue3 is made, first download a copy of the source code from github to your local computer, just like the vue2 source code analysis.

Next is to install the dependencies:

yarn --ignore-scripts

When you execute the command, you may encounter an error that the node version is too low:

To solve this problem, you can upgrade your node version or ignore the engine.

If you choose to ignore, you can set

yarn config set --ignore-engines true

Then perform dependency installation.

After the dependencies are installed, compile and package to generate vuejs files:

yarn-dev

If you need to debug, you can create a test file under the packages\vue\examples file. To reference the packaged vue file, you can apply packages\vue\dist\vue.global.js.

🍲vue3 usage

I will not elaborate on the features of vue3. As far as the usage of vue3 is concerned, it is more inclined to functional programming. By exposing the createApp() API in Vue, an application instance is created in the form of a factory function. Compared with the new Vue instance of vue2, it is more appropriate.

In the source code file, we create a new init.html file.

<script src="../dist/vue.global.js"></script>
 <body>
  <div id="app">{{name}}</div>
  <script>
    const { createApp } = Vue
    const app1 = createApp({
      data() {
        return {
          name: 'clying'
        }
      },
      setup() {
        return {
          name: 'deng'
        }
      }
    }).mount('#app')
  </script>
</body>

According to the above example, we can see that vue3 supports both Composition API and Options API, and both can be used at the same time.

However, we can see that in both data and setup, I used a name variable for assignment. So which one will be displayed on the page?

3!2!1! Previous answer:

It can be clearly seen that setup has a higher priority in composition-api.

Of course, you can also see in the source code packages\runtime-core\src\componentPublicInstance.ts that the switch is used to first determine whether the variable in setup exists, and then to determine the variable in data. Therefore, the priority of variables in setup is higher than that of variables in data.

🍖 Implementation

Through the above usage, we can know that vue3 will expose a Vue variable to the outside world, and there are methods such as createApp and reactive inside.

Here, we first implement the initialization framework of vue3. As for createApp, it receives the parameters passed in by the user: data(), setup(), etc., and finally mounts the instance. Therefore, some parameter options will be received in createApp, and there will also be a mount method inside.

const Vue = {
    createApp(options) {
      return {
        mount(selector) { //parse, get render, mount}
      }
    }
}

Get the host element through the selector in mount.

The next step is to compile the template. After compiling the template into AST, it still needs to be converted into a render function. Here we simplify the operation and directly return a render at compile time.

mount(selector) { //parse, get render, mount const parent = document.querySelector(selector)
  console.log(parent);
  if (!options.render) {
    // Compile and return render
    options.render = this.compileToFunction(parent.innerHTML)
  }
},
compileToFunction(template) {
  return function render() {
    const h = document.createElement('div')
    h.textContent = this.name
    return h
  }
}

After getting render, execute it, add it to the host element, and delete the old node.

When executing render, we need to pay attention to its this pointer. If you bind data to it, it will display the name in the data.

mount(selector) { //parse, get render, mount const parent = document.querySelector(selector)
  console.log(parent);
  if (!options.render) {
    // Compile and return render
    options.render = this.compileToFunction(parent.innerHTML)
  }
  // Execute render 
  const el = options.render.call(options.data())
  parent.innerHTML = ''
  parent.appendChild(el)
},

You can see that clying is displayed on the page. On the contrary, if options.setup() is bound, deng will appear on the page.

For the usage of vue3, we know that setup has a higher priority than data. Then we can use the proxy to combine the attribute variables of the two together through the proxy, giving priority to setup. When accessing the same name, the name in setup is actually accessed.

mount(selector) { //parse, get render, mount const parent = document.querySelector(selector)
  console.log(parent);
  if (!options.render) {
    // Compile and return render
    options.render = this.compileToFunction(parent.innerHTML)
  }
  if (options.setup) {
    this.setupState = options.setup()
  }
  if (options.data) {
    this.data = options.data()
  }
  this.proxy = new Proxy(this, {
    get(target, key) {
      if (key in target.setupState) {
        return target.setupState[key]
      } else if (key in target.data) {
        return target.data[key]
      }// There may be other variables with the same name such as props and watch}, 
    set(target, key, value, newVal) {
      console.log(target, key, value, newVal);
    }
  })
  // Executing render this.proxy is the context that integrates setup and data const el = options.render.call(this.proxy)
  console.log(el, options.render);
  parent.innerHTML = ''
  parent.appendChild(el)
},

In the proxy get, first check whether the target attribute exists in setup. If so, the attribute variable in setup is returned, otherwise the attribute variable in data is returned. When rendering, simply pass in the integrated variable set. Of course, there will also be a set method in the proxy. You need to proxy first, and then get the variables externally to make modifications before it can be triggered. Students who are interested can study it on their own!

Summarize

This is the end of this article about the simple implementation of vue3 source code analysis. For more relevant vue3 source code analysis content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue3.0 responsive system source code line by line analysis
  • Vue3 source code guide (recommended)
  • Implementation method of Vue3.x source code debugging

<<:  Detailed tutorial on setting up multiple instances of MySQL 8 on CentOS 7 (you can have as many as you want)

>>:  Alibaba Cloud applies for a free SSL certificate (https) from Cloud Shield

Recommend

A brief analysis of the function calling process under the ARM architecture

Table of contents 1. Background knowledge 1. Intr...

How to view image information in Docker

In this article, we will need to learn how to vie...

JavaScript to achieve stair rolling special effects (jQuery implementation)

I believe everyone has used JD. There is a very c...

Mybatis mysql delete in operation can only delete the first data method

Bugs As shown in the figure, I started to copy th...

Can MySQL's repeatable read level solve phantom reads?

introduction When I was learning more about datab...

How to implement scheduled backup of CentOS MySQL database

The following script is used for scheduled backup...

Example code for evenly distributing elements using css3 flex layout

This article mainly introduces how to evenly dist...

An article tells you how to implement Vue front-end paging and back-end paging

Table of contents 1: Front-end handwritten paging...

How to deploy your first application with Docker

In the previous article, you have installed Docke...

A brief understanding of the relevant locks in MySQL

This article is mainly to take you to quickly und...

25 Examples of News-Style Website Design

bmi Voyager Pitchfork Ulster Grocer Chow True/Sla...

Summary of Linux commands commonly used in work

Use more open source tools such as docker and kub...

How to configure Nginx virtual host in CentOS 7.3

Experimental environment A minimally installed Ce...

Detailed explanation of WeChat Mini Program official face verification

The mini program collected user personal informat...