This is the 9th day of my participation in the August More Text Challenge. For details, see:August is more challenging
-
The dist folder contains many different versions of VUE
-
There are many examples in the Examples folder
-
Compiler converts the template to the render function, which returns vDOM
-
Core/Components Components of the VUE
-
The Golbal-API defines static methods for vue
- Vue.component .filter .use .extend mixin
-
instace
- Where Vue instances are created, lifecycle, etc
-
observer
-
Responsive data binding is complete
-
vdom
-
Virtual dom
Step 1: Debug
Set –sourcemap “rollup -w-c scripts/config.js –sourcemap –environment TARGET:web-full-dev to automatically open the sourcemap
TARGET:web-full-dev TARGET is an environment variable attribute, and web-full-dev is an environment variable attribute
During debugging, you can view the call Stack information in a method, and you can clear the call Stack information for that method
The compiler is about 3,000 lines of code
Umd supports CommonJS, AMD, and mounting directly to global objects. A generic modular version that supports multiple modular modes
Commonjs is used with older packaging tools such as WebPack1, Browserify, etc.
The ES Module provides support for modern packaging tools
The ES module supports static analysis for tree-shaking,
Tree-shaking is a new implementation of DCE.
DCE:
• Code is not executed and is not reachable • The results of code execution are not used • Code only affects dead variables (write not read)Copy the code
Why is it possible for esModule to do tree-shaking but not for CommonJS
- ES6 module dependencies are defined, and the external interface is just a static definition that is generated during the static code parsing phase. The ability to do reliable static analysis, independent of runtime state, is the basis for Tree-shaking.
- Commonjs loads an object (module.exports) that is generated only after the script has run.
View the configuration of webPack for creating a project using vue-CLI
vue inspect > output.js
If there are generics in flow that cause vscode to fail to parse the syntax and highlight the keywords, you can download the babel-javascript plug-in.
Patch is to convert the virtual DOM to the real DOM, and $mount is to mount the real DOM to the page
In the version with Compiler, the compiler function is provided in the $mount method
Debug Vue, in the core/instance/index.js file, initMixin function on the breakpoint, debug the right menu on the watch Vue constructor, start debugging
-
Start the initMixin function, first mount the _inti function on vue. prototype, and end the initMixin function
-
Start the stateMixin function
[[email protected]] [[email protected]] [[email protected]] [[email protected]] [[email protected]] [[email protected]] [[email protected]]
Set =set vue.prototype. set=set vue.prototype. set=setVue.prototype.delete = del
$watch = ƒ (expOrFn, cb, options)
-
Start the eventMixin method
$on: ƒ (event, fn)
3.2 vue.prototype. $once: ƒ (event, fn)
$off: ƒ (event, fn)
3.4 the Vue. Prototype. $emit: ƒ (event)
-
Start the lifecycleMixin method
4.1 Vue.prototype._update: ƒ (vnode, hydrating)
4.2 the Vue. Prototype. $forceUpdate: ƒ ()
4.3 the Vue. Prototype. $destroy: ƒ ()
-
Start the renderMixin method
5.1 Define methods to help render. Different vDOM conversion methods are required for different types of elements in the Render function
These methods are created inside installRenderHelpers(vue.prototype)
1._b: *ƒ bindObjectProps(data, tag, value, asProp, isSync)*2._e: * ƒ (text) *3._f: * ƒ resolveFilter (id) *4._g: * ƒ bindObjectListeners * (data, value)5._i: * ƒ looseIndexOf (arr, val) *6._init: * ƒ (options) *7._K: *ƒ checkKeyCodes(eventKeyCode, key, builtInKeyCode, eventKeyName, builtInKeyName)*8._L: *ƒ renderList(val, render)*9._M: *ƒ renderStatic(index, isInFor)*10.* _n: * ƒ toNumber (val)11._O: *ƒ markOnce(tree, index, key)*12._q: * ƒ looseEqual * (a, b)13.* * ƒ _s: toString (val)14._t: *ƒ renderSlot(name, fallback, props, bindObject)*15._u: * ƒ resolveScopedSlots (FNS,// see flow/vnode res )* 16._update: * ƒ (vnode, hydrating) *17._v: * ƒ createTextVNode * (val)Copy the code
5.2 the Vue. Prototype. $nextTick: ƒ (fn)
5.3 the Vue. Prototype. And _render: ƒ ()
The patch function is called in _render.
After the core/instance/index.js file is executed, Vue is exported.
The core/index.js file is executed.
-
Execute the initGlobalAPI(Vue) method, which defines the large Vue static method.
DefineProperty (Vue, ‘config’, configDef);
1.1.1 For config objects, emmm… In.. /config file.
Add a util object to the large Vue. This object contains some methods.
Vue.util = { warn, extend, mergeOptions, defineReactive } ps: These tools are not considered part of the global API, and do not rely on them unless you are aware of certain risksCopy the code
1.3 Adding static methods to large Vue
// Add static method set/delete/nextTick Vue.set = set Vue.delete = del Vue.nextTick = nextTick Copy the code
1.4 Add observable method to large Vue to make incoming objects responsive. Can respond? How can it respond? Below said…
Vue.observable = (obj) = > { observe(obj) return obj } Copy the code
1.5 Define the vue. options Object with object.create (null) and initialize the vue. options Object as
Vue.options = Object.create(null) // initialize to Vue.options = { components: {} directives: {} filters: {}}Copy the code
1.6 Record the large Vue itself
Vue.options._base = Vue
1.7 Shallow copy the built-in keep-alive component to Vue.options.components.
extend(Vue.options.components, builtInComponents)
1.8 Register some other methods on large Vue
// Register vue.use () to register the plugin initUse(Vue) // Register vue.mixin () to implement mixin, global initMixin(Vue) This.options = mergeOptions(this.options, mixin) // Register vue.extend () to return a component constructor based on the options passed in initExtend(Vue) Copy the code
Q: How do I deeply merge two objects?
1.9 Register vue.directive (), Vue.component(), vue.filter ()
initAssetRegisters(*Vue*)
Because the three are used in the same way and the parameters passed are not very different, a function is used to handle them
-
Export large Vue
Start initializing platform-specific content
In/platforms/web/runtime/index in js
- Stores platform-specific directives and components
extend(Vue.options.directives, platformDirectives)// Store the global command v-show v-model
extend(Vue.options.components, platformComponents)// Store global components
/ / stored in the Vue. Options. Directives/components
Copy the code
-
Register a patch function to convert the VDOM to the real DOM
Vue.prototype.__patch__ = inBrowser ? patch : noop Copy the code
-
Register the $mount method
Vue.prototype.$mount = function ( el?: string | Element, hydrating?: boolean ) :Component { el = el && inBrowser ? query(el) : undefined return mountComponent(this, el, hydrating) } Copy the code
-
Export Vue
If we were using the compiler version, it would go to platforms/web/entry-runtime-with-compiler.js.
-
Retain/platforms/web/runtime/index of js $mount method
const mount = Vue.prototype.$mount
-
Override the $mount method because you need to convert el or template to the render function.
- The $mount method in /runtime/index.js is passed to render by the default user. Otherwise, an error is reported.
- This function is an addition to the compiler function, which compiles the template to the render function.
new Vue
Enclosing _init method
The this._init method is called inside the constructor.
Vue. Prototype. _init method
- Merge the options passed in
if (options && options._isComponent) { // If it is a component
initInternalComponent(vm, options)
} else { // Not a component
// The options passed by the user are merged with the options in the Vue constructor
vm.$options = mergeOptions(
resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}
Copy the code
-
Set the proxy object that will be used during rendering
vm._renderProxy = vm
-
Initialize the current instance
// Initialize the lifecycle of the parent and child components initLifecycle(vm) // Initialize the current component's events, and the parent component's events bound to the current component initEvents(vm) // $slots/$scopedSlots/_c/$createElement/$attrs/$listeners initRender(vm) callHook(vm, 'beforeCreate') // Dependency injection initInjections(vm) // resolve injections before data/props // Initialize the _props/methods/_data/computed/watch of the VM and inject their members into the vue instance. initState(vm) initProvide(vm) // resolve provide after data/props Copy the code
-
callHook(vm, ‘created’)
-
Start mounting to the page
if (vm.$options.el) { vm.$mount(vm.$options.el) } Copy the code
-
Make a series of judgments
.
-
Start the mount method
The template is used to create the render function and then convert it to a component. To actually mount the page, you need the mount method or the EL property.
Execute the mount method (/runtime/index.js)
Vue.prototype.$mount = function (
el?: string | Element,
hydrating?: boolean
) :Component {
el = el && inBrowser ? query(el) : undefined
return mountComponent(this, el, hydrating)
}
Copy the code
Execute the mountComponent method
Ps: mountComponent method is platform independent.
-
Determine if there is a render function, if not
-
callhook beforeMount
-
Define the core method, updateComponent.
updateComponent = () = > { vm._update(vm._render(), hydrating) } Copy the code
-
Where do I execute the updateComponent method?
- Create the Watcher and execute updateComponent in the constructor of the watcher
new Watcher(vm, updateComponent, noop, { before () { if(vm._isMounted && ! vm._isDestroyed) { callHook(vm,'beforeUpdate')}}},true /* isRenderWatcher */) Copy the code
-
callhook mounted
subtotal
- There are three types of watcher
- Render the watcher
- Calculate attribute
- Related to lazy, whether to delay execution
- The listener
Data response
Data-responsive and bi-directional binding mechanisms are the cornerstones of using data-driven development, where pages are automatically updated when data changes.
The entry point for reactive processing, the this._init method calls the initState method (which initializes the properties of the instance).
Look at the initData method here, which initializes the data property.
- Assign data to vm._data
- For data proxy, this.name proxy to this._data.name. This.name = ‘a’ agent to this._data.name = ‘a’
- Observe for data.
- Return the value of the __ob__ attribute if the data object has an __ob__ attribute.
- If not, ob = new Observer(value) return ob
- Each instance of a data object has a __ob__ attribute. Its value is instanceof an instanceof the Observer
- If it is an object enter this. Walk method. Go through the data object and get and set each property. Collect dependencies, trigger updates, etc
The role of the Observer class
- The Observer class is attached to every object that needs to be observed. Once attached, the Observer class converts each property of the observed object to getters and setters that collect dependencies and dispatch updates.
Observation model
- The observer pattern could also be called a publish-subscribe pattern (but without the middleman). In vUE, the DEP publishes information notifying Watcher of the change. That means deP is the publisher and Watcher is the subscriber. Watcher can also be called a dependency, and DEP can also be called a collection of dependencies.
- Each reactive data has a DEP attribute. When accessing this attribute, dependencies are collected. Watcher objects that depend on this attribute are added to the subs array of the DEP object. Notifies all Watchers in the subs array to update (watcher.update).
Reactive ps
Initialize, then execute, compile el to render, then mount, then mountComponent, in mountComponent
new Watcher(vm, updateComponent, noop, {
before () {
if (vm._isMounted && ! vm._isDestroyed) {
callHook(vm, ‘beforeUpdate’)
}
}
}, true /* isRenderWatcher */)
In the Watcher constructor, if not the lazy property is false, the get function is executed. The first line of the get function is pushTarget(this), which represents the current Watcher, and then dep. target = target, Dep. Target is used to store the watcher that is currently in use. In Vue, each component corresponds to a Watcher object. Dep.target is a property on the Dep class. The Dep class is unique, so Dep. Target is unique. Because import is a reference to a value.
Q: How to render if parent and child components are nested?
A: Use the stack structure to define the parent-child relationship. After the child component is rendered, pop up the watcher of the child component and point dep. target to the last watcher in the stack.
Start executing the updateComponent method… {{name}} –> this.name
get: function reactiveGetter () { const value = getter ? getter.call(obj) : val if (Dep.target) { dep.depend() if (childOb) { childOb.dep.depend() if (Array.isArray(value)) { dependArray(value) } } } return value }
dep.depend() –>
depend () {
if (Dep.target) {
Dep.target.addDep(*this*) Copy the code
}
}
On the get property, trigger Watcher’s addDep method (which takes the instance of dep) and determine if the dep is in the Watcher instance’s newDepIds set. If not, call the dep’s addSub method. Place the Watcher instance in the SUBs array of the DEP.
Q: Why not just use dep.addsub (dep.target) when getting?
A: If {{age}} {{age}} {{age}} {{age}} {{age}} {{age}} {{age}} {{age}} {{age}} {{age}} {{age}} {{age}} {{age}} {{age}} {{age}} {{age}} {{age}} Does the update trigger four watcher updates? Obviously, this is not reasonable. So Vue uses a kind of interlog rule, where each watcher keeps track of all the DEPs that the watcher uses, and the DEPs keep track of all the Watchers that the DEP depends on.
So: DeP records all dependent watcher and stores it in subs array for update.
Record all dePs used in the watcher and check whether the watcher is added repeatedly. There should be one more small detail.
Three kinds of watcher
- computed
- $watch
- Render the watcher
The order of creation is computed/Watch/render watcher, as is the order of execution watcher
- Computed the watcher
In the initComputed function
// create internal watcher for the computed property.
watchers[key] = new Watcher(
vm,
getter || noop, // The getter is the function passed in by the user
noop,
computedWatcherOptions // { lazy: true }
)
Copy the code
- Watch the watcher
In the initWatch function
The watcher for watch is the watcher created in the vue.prototype. $watch function
// Monitor data changes
Vue.prototype.$watch = function (
expOrFn: string | Function.// The user defines watcher as a key
cb: any, Watcher is a function in Handler, or methodsoptions? :Object // This is a configuration item
) :Function {
const vm: Component = this
if (isPlainObject(cb)) {
return createWatcher(vm, expOrFn, cb, options)
}
options = options || {}
options.user = true
const watcher = new Watcher(vm, expOrFn, cb, options)
if (options.immediate) {
try {
cb.call(vm, watcher.value)
} catch (error) {
handleError(error, vm, `callback for immediate watcher "${watcher.expression}"`)}}return function unwatchFn () {
watcher.teardown()
}
}
Copy the code
- Render the watcher
In the mountComponent function.
new Watcher(vm, updateComponent, noop, {
before () {
if(vm._isMounted && ! vm._isDestroyed) { callHook(vm,'beforeUpdate')}}},true /* isRenderWatcher */)
Copy the code
The computed to perform
Computed is yueleu…. Responsible for pulling strings, and finally executing the data in data.
-
Create the Watchers object, watchers = vm._computedWatchers = {}
-
UserDef = getter for the passed function, reversedMessage() {return this.message.split(“).reverse().join(“)}
-
Create watcher with parameters vm, getter, noop, {lazy: true}
- The watcher object’s getter property is the getter(passed in function)
- Set the value for the Watchers object, watchers[key] = new Watcher
-
Execute the defineComputed (VM, key, userDef) function. Returns the function assigned to sharedPropertyDefinition. Get.
-
Seized properties
*Object*.defineProperty(*target*, *key*, sharedPropertyDefinition)
Initialization completed
To get this data, execute the function returned by the createComputedGetter function
return function computedGetter () {
const watcher = this._computedWatchers && this._computedWatchers[key]
if (watcher) {
if (watcher.dirty) { // If the first time is true, execute watcher's get function, which will
watcher.evaluate() // this(watcher).value = value
}
if (Dep.target) {
watcher.depend()
}
return watcher.value
}
}
Copy the code
nextTick
The Watcher function flushSchedulerQueue is used to flushSchedulerQueue the Watcher object to be added to the queue. The Watcher function flushSchedulerQueue is used to flushSchedulerQueue the Watcher object. Watcher executes asynchronously, because the flushSchedulerQueue method executes in the nextTick method.
- () => cb()push to the callbacks array and execute the timerFunc method to flushCallbacks
- $nextTick was not used during the initial render, but will be used during the update. Or the user calls it
- Function: Retrieve the latest data from the DOM. When the microtask executes, the dom element has not yet been rendered to the browser. The callback function in the nextTick immediately sends a notification informing the watcher that the render view has changed. But the first thing Watcher did was to update the data on the DOM. Once the update was done, the nextTick method passed by the user was executed to get the latest data
- Why?
- Because if it changes, it goes to watcher’s update method, which goes to queueWatcher(thisNextTick (flushSchedulerQueue); nextTick(flushSchedulerQueue); timerFunc(); flushCallbacks (); Then our user manually called the nextTick method,… It’s going to execute the timerFunc method, and it’s going to execute it in the microtask.
- Multiple NextTicks passed by the user (or flushSchedulerQueue if a data change triggers watcher’s update method) are placed in an array for sequential execution within the same microtask. NexTick is a synchronous method, executing its contents is an asynchronous method.
Virtual dom
- The essence of the virtual DOM is that javascript objects are used to describe the real DOM
- The changes in the state of the application first affect the virtual DOM and then map to the real DOM, and the framework helps us mask the dom’s operations.
- Vdom in VUE borrows from SNabbDOM and adds features of VUEJs
- Added: directive and component mechanisms
- Why use VDOM
- Avoid direct manipulation of the DOM to improve development efficiency.
- The virtual DOM, as a middle tier, can be cross-platform
- Vdom does not necessarily improve performance
- The first rendering adds overhead, as there is an extra layer of virtual DOM maintenance (creating additional complex JS objects)
- Improved rendering performance in complex view situations
- If there are frequent DOM operations. Before the virtual DOM updates the real DOM, the diff algorithm will be used to compare the differences between the old and new virtual DOM trees and finally update the differences to the real DOM instead of updating the real DOM every time. By setting the key attribute for the node, the node can be reused and a large number of redrawings can be avoided.
Template compilation
Template:
<div id="app">
<h1>Vue<span>Template compilation process</span></h1>
<p>{{ msg }}</p>
<comp @myclick="handler"></comp>
</div>
Copy the code
Render function:
(function anonymous(
) {
with(this){
return _c(
'div',
{attrs: {"id":"app"}},
[
_m(0), // The renderStatic function handles static content. Static content is optimized during template processing.
_v(""), // The newline generates a blank node
_c('p',[_v(_s(msg))]),
_v(""),
_c('comp', {on: {"myclick":handler}})
],1)}})Copy the code
What is an abstract syntax tree
- Abstract Syntax tree is called AST for short
- Describe the tree code structure in the form of an object
- The abstract syntax tree here is an HTML string used to describe the tree structure
Why use abstract syntax trees
- After a template string is converted to an AST, you can optimize the template using the AST
- Mark the static content in the template, and directly skip the static content during patch
- Static content does not need to be compared and re-rendered during patch
HTML string
<p v-if="msg">{{ msg }}</p>
<ul>
<li v-for="item in arr" :key="item">{{item}}</li>
</ul>
<comp @myclick="handler"></comp>
Copy the code
<p v-if="msg">{{ msg }}</p>
attrsMap: {v-if: "msg"}
rawAttrsMap:
v-if: {name: "v-if", value: "msg" }
static: false
staticRoot: false
Copy the code
<ul>
<li v-for="item in arr" :key="item">{{item}}</li>
</ul>attrsList: [] attrsMap: {} children: alias: "item" attrsList: [] attrsMap: :key: "item" v-for: "item in arr" for: "Processed: True Key:" Item "rawAttrsMap: {v-for: {... }, : key: {... }} static: false staticRoot: false tag: "li" type: 1Copy the code
The generated render function and staticRenderFns function
render:
"with(this){return _c('div',{attrs:{"id":"app"}},[_m(0),_v(" "),(msg)? _c('p',[_v(_s(msg))]):_e(),_v(" "),_c('ul',_l((arr),function(item){return _c('li',{key:item},[_v(_s(item))])}),0),_v(" "),_c('comp',{on:{"myclick":handler}})],1)}"
Copy the code
staticRenderFns:
["with(this){return _c('h1',[_v("Vue"),_c('span',[_v("Template compilation process")]])}"]
Copy the code
_m(0) in render corresponds to the data whose index is 0 in the array of return in staticRenderFns
The static root node will be marked, and the static root node will be optimized. The static root node does not need to be processed when re-rendering, because its content will not change. Do not write too much meaningless white space and line breaks in the template, otherwise the generated AST object will retain these line breaks and be stored in memory. These white Spaces and line breaks are meaningless for browser rendering.
component
Vue components:
- A Vue component is an instance of Vue with predefined options.
- A component can form a fully functional area on a page. A component can contain scripts, styles, and templates.
Vue.extends
- The component constructor is created based on the options object passed in. The constituent constructor inherits from Vue’s constructor, so the component constructor has the same members as Vue.
Component Registration Process
Component creation process
Component Patch process
Please describe the first rendering process of Vue.
1. Large Vue is initialized
Start with the packaged entry file/SRC /platforms/web/ entry-Runtime-with-compiler. js
The initialization of vue begins with the introduction of vue.js. We start with the packaged entry file.
Vue is introduced in the /runtime/index file
Vue is introduced in the core/index file
Vue is introduced in the./instance/index file
Function Vue() {};
The reason why Vue is defined as a function rather than a class is to allow instance members to be mixed into the Vue instance later.
The contents of this file mainly inject member methods into instances of Vue
4.1, initMixin (Vue)
-
The _init method is defined for the Vue instance object
4.2. StateMixin (Vue) initializes some properties of the Vue instance
- Mount data and data and data and data and prop properties to the instance
// Mount the $data and $prop properties to the instance
Object.defineProperty(Vue.prototype, '$data', dataDef)
Object.defineProperty(Vue.prototype, '$props', propsDef)
Copy the code
2. Mount set and set and set and DELETE to the instance
Vue.prototype.$set = set
Vue.prototype.$delete = del
Copy the code
3. Mount the $watch method to the instance
4. The return value is a function that can be used to cancel the current listener.
4.3 eventsMixin(Vue) Initializes event-related methods
- Mount the on, ON, ON, once, off, off, off, off, emit methods on the instance
-
on = function (event: string | Array<string>, fn: Function): vm -
once = function (event: string, fn: Function): vm -
off:off: off:off = function (event? : string | Array
, fn? : Function): vm
-
emit = function (event: string): vm4.4 lifecycleMixin(Vue) initializes lifecycle related methods
-
Mount the _update(vnode: vnode), forceUpdate,.forceUpdate,.forceUpdate, and.destroy methods to the instance
4.5, renderMixin (Vue)
- Define the helper functions that help the render function render
- Mount the $nextTick(fn: Function) and _render: VNode methods on the instance
4.6 the export default Vue
- At this point, the instance/index file is complete.
Enter core/index
InitGlobalAPI (Vue) is executed, which defines the static methods of the large Vue
5.1 Define config properties for large Vue
1. The values of config are some configuration objects of the current Vue
5.2 Defining the util object
// These tools are not considered part of the global API, so don't rely on them unless you are aware of certain risks
Vue.util = {
warn,
extend,
mergeOptions,
defineReactive
}
Copy the code
5.3 Defining static methods
// Static method set/delete/nextTick
Vue.set = set
Vue.delete = del
Vue.nextTick = nextTick
Copy the code
5.5 a new responseable object API added in version 2.6
// Let an object respond
Vue.observable = (obj) = > {
observe(obj)
return obj
}
Copy the code
5.6 Initialize the vue. options object and extend it
// components/directives/filters
Vue.options = Object.create(null)
ASSET_TYPES.forEach(type= > {
// Mount three members to vue. options
Vue.options[type + 's'] = Object.create(null)})Copy the code
5.7 Recording the large Vue constructor
Vue.options._base = Vue
5.8 Copy the keep-Alice built-in components to Vue.options.components
extend(*Vue*.options.components, builtInComponents)
5.9 Register some other global static apis
// Register vue.use () to register the plugin
initUse(Vue)
// Register vue.mixin () to implement mixin, global
initMixin(Vue)
// Register vue.extend () to return a component constructor based on the options passed in
initExtend(Vue)
// Register vue.directive (), Vue.component(), vue.filter ()
initAssetRegisters(Vue)
Copy the code
5.10 export
Export Vue, at which point core/index ends
Enter Runtime /index
6.1 Register platform-related directives and components
// Extend the second argument (object) to the first argument (object).
extend(Vue.options.directives, platformDirectives)// Store the global command v-show v-model
extend(Vue.options.components, platformComponents)// Store global components
// Global directives and components are stored in vue.options.directives and vue.options.directives, respectively.
Copy the code
6.2 Register a patch function for the VUE instance to convert the VDOM to the real DOM
Vue.prototype.__patch__ = inBrowser ? patch : noop
6.3 Registering mounted Components $mount
// public mount method
Vue.prototype.$mount = function (
el?: string | Element,
hydrating?: boolean
) :Component {
el = el && inBrowser ? query(el) : undefined
return mountComponent(this, el, hydrating)
}
Copy the code
6.4 export Vue
- Runtime /index ends at this point
7. Enter the entry-Runtime-with-compiler entry file
7.1 Retain the $mount method for the vue instance,
1. When did not render method, need to use the $mount method of rewriting the template to render function, and then to mount function calls to retain.
7.2 Overwriting the $mount method
1. Change the template to render function.
7.3 Expose a static method, Vue.compile
// Compile the HTML string into the render function
Vue.com compile(' hello world
')
Vue.compile = compileToFunctions
Copy the code
7.4 export Vue
1. Thus, the entry-runtime-with-compiler is completed. The entire initialization is complete
Summary: This is the initialization process for large Vue