Vue, now the front end of the red fried chicken, with the heat index rise, it is necessary to realize the principle of its function from the point of view of the source. Personally feel to see the source code is mainly to see two things, from the macro is its design ideas and implementation principle; Microcosm is programming skills, also known as the SAO operation. We’ll focus on how it works this time. Well, let’s push open its mysterious doors and enter the world of Vue

What is vue?

What exactly is vue? I don’t know if you’ve ever thought about why you can implement so many cool features. Each time you initialize a vue, use new vue ({… }), it’s not hard to see that vue is actually a class. But even with the popularity of ES6 today, the definition of vue is defined by a generic constructor. Why not adopt ES6 class? We’ll answer that later, but after a few layers of tracking down where vue is defined:

function Vue(options) {
  ...
  this._init(options)
}
Copy the code

Because it is the principle of analysis, flow type detection and some boundary cases, such as the use of the wrong way or parameter is not the main logic of the code we omit it. Ellipsis, for example, where the boundary case must be new Vue(), otherwise an error will be reported.

In fact, the vue source code is like a tree. It is best to decide what functionality to look at before we look at it, and then avoid the bifurcation logic. Our next goal is to start with new Vue() and go through the entire process from initialization, data, templates to the real Dom.

This is where vUE was originally defined, you read that right, it’s as simple as that. When new Vue is executed, a method this._init(options) is executed internally, passing in the initialization parameters.

It is important to note that, inside vUE, variables defined with the _ sign are for internal private use, while variables defined with the $sign are for user use, and user-defined variables cannot start with an _ or $to prevent internal conflicts. Let’s move on:

import { initMixin } from './init'
import { stateMixin } from './state'
import { renderMixin } from './render'
import { eventsMixin } from './events'
import { lifecycleMixin } from './lifecycle'

function Vue(options) {
  ...
  this._init(options)
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)
Copy the code

Now we can answer the previous question, why not use the ES6 class definition, because it is easy to split the vue function into different directories to maintain, passing the vue constructor into the following methods:

  • InitMixin (Vue) : definition_initMethods.
  • StateMixin (Vue) : Defines data related methods$set.$delete.$watchMethods.
  • EventsMixin (Vue) : Defines event-related methods$on.$once.$off.$emit.
  • LifecycleMixin (Vue) : definition_update, and life cycle related$forceUpdateand$destroy.
  • RenderMixin (Vue) : definition$nextTick._renderConvert the render function tovnode.

These methods are maintained in their own files, making the code structure more legible and maintainable. For example, the this._init method is defined in:

export function initMixin(Vue) {
  Vue.prototype._init = function(options) { ... When new Vue is executed, perform a series of initializations and mount}}Copy the code

After these xxxmixins are complete, some global apis are defined:

export functionInitGlobalAPI (Vue) {vue.set method vue.delete method vue.nexttick method... Built-in components: keep-alive transition transition-group... InitUse (Vue) : vue. use method initMixin(Vue) : vue. mixin method initExtend(Vue) : vue. extend method initAssetRegisters(Vue) : Vue.component.directive, vue.filter method}Copy the code

There are parts of the API that have similar or identical functionality to the xxxmixin-defined prototype methods, such as this.$set and vue. set, which use set as an internally defined method.

The architectural design of VUE needs to be mentioned here. Its architecture is layered. The bottom layer is an ES5 constructor, and the top layer defines _init, $watch, _render, and other methods in the prototype. The top layer defines global apis in the constructor itself, such as set, nextTick, use, etc. (these are platform-independent core code). Cross-platform and server-side rendering (which are beyond discussion for now) and compilers follow. Once these property methods are defined, a complete constructor is finally exported to the user, and New Vue is the key to start. This is the unfamiliar and familiar vue, but what does vue.prototype. _init do inside? We’ll talk about that in the next chapter, because there’s a lot more to add.

The directory structure

Having just taken a closer look at VUE from a micro perspective, let’s take a macro look at how its internal code structure is put together. The directory is as follows:

Version | | - dist vue after packaging - flow type testing, 3.0 intypeScript | | - vue Script to build different versions of the relevant configuration - SRC source | - | compiler compiler - core does not distinguish between platform of the core code | - | components general abstract components - global - API Global API | | - instance instance constructors and prototypes method - the observer response data type | - util method commonly used tools | - vdom virtual dom related | - | - server platforms different platform implementation Server side rendering | -- SFC. Vue single file component analytical | | -- - Shared global universal tool methodtesttestCopy the code
  • Flow: javaScript is a weakly typed language that uses flow to define and detect types, increasing the robustness of code.

  • SRC /compiler: Compile the template template into the render function.

  • SRC /core: platform-independent generic logic that can run in any javaScript environment, such as web, Node.js, weex embedded native applications.

  • SRC/Platforms: Separate implementations for Web and WEEX platforms, and provide a unified API to call.

  • SRC/Observer: VUE detects data changes to change the view code implementation.

  • SRC/vDOM: Render function to vnode so that the patch is a real DOM and diff algorithm code implementation.

  • Dist: Stores different vUE versions for different uses.

Vue version

Vue is built using rollup. It doesn’t matter how it is built, but many different versions of vUE will be built. According to the different ways of use, it can be divided into the following three categories:

  • UMD:<script>The tag is used directly in the browser.
  • CommonJS: Use an older packaging tool, such aswebpack1.
  • ES Module: Used with modern packaging tools, such aswebpack2And above.

And each use is divided into the full version and runtime version, here mainly to ES Module as an example, with the official scaffolding of the other two types should not be used by many people. Before I explain the differences between the two versions, I’m sorry to add something else. Inside vue we only recognize the render function, let’s define our own render function, namely this thing:

new Vue({
  data: {
    msg: 'hello Vue! '
  },
  render(h) {
    return h('span', this.msg); }}).$mount('#app');
Copy the code

You might wonder if we’ve never written the render function, but used the template. This is because of vue-loader, which compiles the content we defined in the template into the render function. This compilation is the key to distinguish the full version from the runtime version. The full version comes with the compiler, but the runtime version does not.

new Vue({
  data: {
    msg: 'hello Vue! '  
  },
  template: `<div>{{msg}}</div>`
})
Copy the code

Vue – CLI uses the runtime version by default, change or overwrite the default configuration in scaffolding, change it to the full version and compile: ‘vue$’: ‘vue/dist/vue.esm.js’, the runtime version is recommended. Okay, so we’ll end this chapter with a question that’s often asked in an interview.

The interviewer smiled and politely asked,

  • Excuse me,runtimeandruntime-onlyWhat’s the difference between the two versions?

Dui back:

  • There are two main differences:
  1. The most obvious difference is the size, with the compiler being larger than the version without6kb.
  2. The compilation time is different, the compiler is run time compilation, performance will have a certain loss; The runtime version is aided byloaderDo offline compilation, running performance is higher.

What does new Vue() do when you quickly understand it? (on)

Easy to click a like or follow bai, also easy to find ~

Reference:

Vue. Js source code comprehensive in-depth analysis

Vue.js is easy to understand

Share a component library for everyone, may use up ~ ↓

A library of vUE functional components that you might want to use.