Start at the entrance, interpret the Vue source code (1)--Creation

Why?

There are a large number of existing Vue source code analysis articles on the Internet, but why should I do such a thing? Because I think 纸上得来终觉浅,绝知此事要躬行.

Then the usual projects are mainly Vue. In the process of using Vue, I also have some questions about some of its conventions. Maybe the official website will only recommend you to do so, but we may not know the core implementation. for example:

  • How v-for key achieves the "in-place reuse" strategy
  • How array update detection is done
  • Why can set dynamically add root-level responsive properties
  • Why Vue can support weex across platforms, and later mpvue
  • ...

Secondly, I haven't updated the content for a long time. I did some research on the Vue source code before, but I didn't have a very systematic record. Now I took some time and made a basic summary. On the one hand, it is because I want to overcome my inertia, and on the other hand, I want to revisit the past.

What?

It is divided into 10 basic parts in total, which will continue to be recorded in the future. Let's take a look at the overview first:

Then let's take a look at the base directory:

Start at the entrance, interpret the Vue source code (1) —— Creation

Start at the entrance, interpret the Vue source code (2) - the story of new Vue

Start at the entrance, interpret the Vue source code (3) - initMixin Part 1

Start at the entrance, interpret the Vue source code (3) - initMixin Part 2

Start at the entrance, interpret the Vue source code (4) - implement a basic Vue two-way binding

Start at the entrance, interpret the Vue source code (5) - the internal implementation of $mount

Start the entry, interpret the Vue source code (6) - $mount internal implementation - compile parse function to generate AST

Start the entry, interpret the Vue source code (7) - $mount internal implementation --- compile optimize mark node

Start at the entrance, interpret the Vue source code (8) - the internal implementation of $mount - compile generate to generate the render function

Start at the entrance, interpret the Vue source code (9) - internal implementation of $mount - render function -> VNode

Start at the entrance, interpret the Vue source code (10) - the internal implementation of $mount --- patch

Beginning: The entrance begins, interpreting the Vue source code (1)--Creation

The origin of all things in the world comes from the creation of Pangu, and the origin of the Vue project comes from an instantiation of Vue:

new Vue({
  el: ...,
  data: ...,
  ....
})

So what exactly happened during this instantiation? Let's find out. Open the source code file of Vue, and its core code is in the src/coredirectory. Let's start from the entry file index.js: (At the beginning, we may not know the specific implementation of each reference method, but it doesn't matter, we can YY according to his name.)

// src/core/index.js

// 这里应该是我们 Vue 核心方法
import Vue from './instance/index'
// 根据命名,应该可以猜出这里是初始化一些全局API
import { initGlobalAPI } from './global-api/index'
// 根据命名,这里应该是获取一个Boolean类型的变量,来判断是不是ssr
import { isServerRendering } from 'core/util/env'
// 这里开始执行初始化全局变量
initGlobalAPI(Vue)
// 为Vue原型定义属性$isServer
Object.defineProperty(Vue.prototype, '$isServer', {
  get: isServerRendering
})
// 为Vue原型定义属性$ssrContext
Object.defineProperty(Vue.prototype, '$ssrContext', {
  get () {
    /* istanbul ignore next */
    return this.$vnode && this.$vnode.ssrContext
  }
})

Vue.version = '__VERSION__'

export default Vue

Let's verify our guess step by step, first find core/instance/indexthe file, you can clearly see:

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

function Vue (options) {
  if (process.env.NODE_ENV !== 'production' &&
    !(this instanceof Vue)
  ) {
    warn('Vue is a constructor and should be called with the `new` keyword')
  }
  this._init(options)
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue

Here, a Vue Class is simply and rudely defined, and then a series of init、mixinsuch methods are called to initialize some functions. We will analyze the details later, but what we can confirm through the code is: Yes! Here is indeed a Vue functional class that is exported.

Next, let's look at initGlobalAPIthis thing. In fact, on the Vue official website , the global properties of Vue have been explained for us:

About the global API

Then let's see if this is the case (too much content, just paste the main code):

// core/global-api/index

...
export function initGlobalAPI (Vue: GlobalAPI) {
  // config
  const configDef = {}
  configDef.get = () => config
  if (process.env.NODE_ENV !== 'production') {
    configDef.set = () => {
      warn(
        'Do not replace the Vue.config object, set individual fields instead.'
      )
    }
  }
  Object.defineProperty(Vue, 'config', configDef)

  // 这些工具方法不视作全局API的一部分,除非你已经意识到某些风险,否则不要去依赖他们
  Vue.util = {
    warn,
    extend,
    mergeOptions,
    defineReactive
  }
  // 这里定义全局属性
  Vue.set = set
  Vue.delete = del
  Vue.nextTick = nextTick

  Vue.options = Object.create(null)
  ASSET_TYPES.forEach(type => {
    Vue.options[type + 's'] = Object.create(null)
  })
  Vue.options._base = Vue
  extend(Vue.options.components, builtInComponents)

  // 定义全局方法
  initUse(Vue)
  initMixin(Vue)
  initExtend(Vue)
  initAssetRegisters(Vue)
}
  • [Vue.config] Various global configuration items

  • [Vue.util] Various tool functions, as well as some compatibility flags (wow, you don't need to judge the browser yourself, Vue has already judged it)

  • [Vue.set/delete] You should have seen this document

  • 【View.nextTick】

  • [Vue.options] This options is different from the options we used to construct the instance above. This is the resource provided by Vue by default (component directive filter).

  • [Vue.use] Defined by the initUse method

  • [Vue.mixin] Defined by the initMixin method

  • [Vue.extend] Defined by the initExtend method

$isServerNext is the global variable and provided to ssr $ssrContext. Regarding their use, in fact, the ssr documentation also states: Head management

At this point, our entry file is almost understood. Next, we start to understand the specific implementation of Vue class, in which we will learn about the knowledge of Vue's related life cycle.

End?

The front and back of the article are also summarized and organized by using fragmented time. Some of them have also read a lot of materials, and there are also paragraphs citing giants, which are marked in the article. If it is not marked, I may have forgotten it, please remind me. If there are clerical errors or incorrect explanations in the article, criticisms and corrections are also welcome for common progress.

finally:

github address

Part of the source code demo

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324820874&siteId=291194637