Deep Dive into Vue 2.0: Initialization, Compilation, Reactivity & Virtual DOM
This article walks through Vue 2.0's core source code, explaining the initialization and mounting process, the three‑stage template compilation (parse, optimize, generate), the reactivity system with dependency collection, and how the virtual DOM and patch algorithm update the view.
Yuan Dong, a front‑end engineer from WeDoctor Cloud Services, shares his journey of dissecting Vue 2.0 source code to understand the fundamentals that later changed in Vue 3.0.
Although Vue 3.0 is popular, studying Vue 2.0 helps grasp the original mechanisms before the new version’s modifications.
The article follows a page‑rendering flowchart to explore Vue’s inner workings.
Initialization and Mounting
new Vue() → $mount
From core/index.js the entry imports Vue: import Vue from './instance/index' In instance/index.js it imports the init mixin:
import { initMixin } from './init' 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); // this Vue parameter is defined in initMixin()The constructor calls this._init(options), which is defined in initMixin().
export function initMixin (Vue: Class<Component>) {
Vue.prototype._init = function (options?: Object) {
const vm: Component = this
// ... omitted intermediate processing
vm._self = vm
initLifecycle(vm) // initialize lifecycle
initEvents(vm) // initialize events
initRender(vm) // initialize render
callHook(vm, 'beforeCreate')
initInjections(vm)
initState(vm) // init props, methods, data, computed, watch
initProvide(vm)
callHook(vm, 'created')
// ... omitted some processing
if (vm.$options.el) {
vm.$mount(vm.$options.el) // mount component after init
}
}
}After new Vue(), Vue calls _init which performs:
export function initState (vm: Component) {
vm._watchers = []
const opts = vm.$options
if (opts.props) initProps(vm, opts.props) // props
if (opts.methods) initMethods(vm, opts.methods) // methods
if (opts.data) {
initData(vm) // data
} else {
observe(vm._data = {}, true)
}
if (opts.computed) initComputed(vm, opts.computed) // computed
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch) // watch
}
}The core of reactivity is using Object.defineProperty to define getters and setters for dependency collection.
(Q1: How does Vue implement reactivity and dependency collection?)
After initialization, $mount mounts the component.
If runtime compilation is used (template without a render function), a compilation step is required.
(Q2: How does Vue compile templates?)
Compilation
Compilation consists of three stages: parse , optimize , and generate , ultimately producing a render function.
Key file:
compiler/index.js import { parse } from './parser/index'
import { optimize } from './optimizer'
import { generate } from './codegen/index'
import { createCompilerCreator } from './create-compiler'
export const createCompiler = createCompilerCreator(function baseCompile (template: string, options: CompilerOptions): CompiledResult {
const ast = parse(template.trim(), options)
if (options.optimize !== false) {
optimize(ast, options)
}
const code = generate(ast, options)
return { ast, render: code.render, staticRenderFns: code.staticRenderFns }
})Call parse to generate an AST.
If options.optimize is true, call optimize to mark static nodes.
Call generate to turn the AST into render code.
Return an object containing the AST, the render string, and static render functions.
parse
Parse analyzes the template with regexes, extracting directives, classes, styles, etc., and builds the AST.
optimize
Optimize marks static nodes, allowing the later patch diff algorithm to skip them and improve performance.
(Q3: How does Vue distinguish static nodes? What does the patch/diff algorithm do?)
generate
Generate converts the AST into a render function string and static render function strings.
After parse, optimize, and generate, the component has a render function ready to produce VNodes.
(Q4: What is a VNode?)
Reactivity
When the render function runs, it reads object properties, triggering the getter to collect dependencies. The collected Watcher objects are stored in a Dep ’s subscriber list.
When a property changes, the setter notifies each stored Watcher, which calls its update method to re‑render the view. The update later involves a patch process and an asynchronous queue.
(Q5: What is the reactivity principle of Vue 2.0?)
Virtual DOM
The virtual DOM is the result of executing the render function: a tree of JavaScript objects (VNode nodes) that abstractly describe real DOM nodes, enabling platform‑agnostic rendering across browsers, Weex, Node, etc.
Updating the View
When a data property changes, the flow is: setter → watcher → update → render → new VNode.
The new VNode is compared with the old one via patch, which runs a diff algorithm to find differences.
Only the changed parts of the real DOM are updated, avoiding full re‑rendering.
Summary
Revisiting the initial diagram, the overall Vue execution flow becomes clear:
Page rendering: new Vue() → init() → $mount() Data update: user action → getter collects deps → dep.depend() → dep.subs.push(watcher) → setter notifies watchers → dep.notify() → watcher.update() → render → VNode → patch → DOM
Template compilation: parse → optimize → generate The series will continue to explore each mechanism in detail; readers are welcome to comment or provide feedback.
References
Juejin e‑book "Analyzing Vue.js Internal Mechanics"
Vue 2.0 source code (https://github.com/Vuejs/cn.Vuejs.org)
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
WeDoctor Frontend Technology
Official WeDoctor Group frontend public account, sharing original tech articles, events, job postings, and occasional daily updates from our tech team.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
