文章目录 一、Vue 核心架构设计 二、响应式系统源码解析 三、虚拟DOM与Diff算法实现 3.1 Diff算法流程图 3.2 核心Diff源码 四、模板编译全流程剖析 五、组件系统与生命周期 六、异步更新队列与性能优化 七、Vue 3 新特性源码对比 八、手写迷你Vue框架实战 总结
一、Vue 核心架构设计
1.1 整体架构流程图
模板/JSX
编译器
渲染函数
虚拟DOM树
Patch算法
真实DOM
数据响应系统
依赖收集
派发更新
1.2 模块职责划分
模块 源码文件 核心职责 响应式系统 src/core/observer 数据劫持/依赖管理 虚拟DOM src/core/vdom VNode创建/Diff/Patch 编译器 src/compiler 模板转渲染函数 组件系统 src/core/instance 组件实例生命周期管理
二、响应式系统源码解析
2.1 核心类关系图
Observer
+walk(data)
+defineReactive()
Dep
+subs: Watcher[]
+depend()
+notify()
Watcher
+get()
+update()
2.2 核心源码分析
2.2.1 数据劫持实现
export class Observer { constructor ( value ) { this . value = valuethis . dep = new Dep ( ) def ( value, '__ob__' , this ) if ( Array. isArray ( value) ) { this . observeArray ( value) } else { this . walk ( value) } } walk ( obj ) { const keys = Object. keys ( obj) for ( let i = 0 ; i < keys. length; i++ ) { defineReactive ( obj, keys[ i] ) } }
} function defineReactive ( obj, key ) { const dep = new Dep ( ) let val = obj[ key] Object. defineProperty ( obj, key, { enumerable : true , configurable : true , get : function reactiveGetter ( ) { if ( Dep. target) { dep. depend ( ) } return val} , set : function reactiveSetter ( newVal ) { if ( newVal === val) return val = newValdep. notify ( ) } } )
}
2.2.2 依赖收集过程
let uid = 0
export default class Dep { static target = null constructor ( ) { this . id = uid++ this . subs = [ ] } depend ( ) { if ( Dep. target) { Dep. target. addDep ( this ) } } notify ( ) { const subs = this . subs. slice ( ) for ( let i = 0 ; i < subs. length; i++ ) { subs[ i] . update ( ) } }
}
三、虚拟DOM与Diff算法实现
3.1 Diff算法流程图
Yes
No
Yes
No
Yes
No
新旧VNode对比
相同节点?
更新属性
替换节点
有子节点?
执行子节点Diff
流程结束
双指针遍历
找到可复用节点?
移动节点
新建节点
3.2 核心Diff源码
function updateChildren ( parentElm, oldCh, newCh ) { let oldStartIdx = 0 let newStartIdx = 0 let oldEndIdx = oldCh. length - 1 let newEndIdx = newCh. length - 1 while ( oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { if ( sameVnode ( oldStartVnode, newStartVnode) ) { patchVnode ( ... ) oldStartIdx++ newStartIdx++ } } if ( oldStartIdx > oldEndIdx) { addVnodes ( ... ) } else if ( newStartIdx > newEndIdx) { removeVnodes ( ... ) }
}
四、模板编译全流程剖析
4.1 编译流程图
Template AST Render 解析器生成抽象语法树 优化器标记静态节点 代码生成器输出渲染函数 Template AST Render
4.2 编译阶段源码
export function compileToFunctions ( template ) { const ast = parse ( template. trim ( ) ) optimize ( ast) const code = generate ( ast) return { render : new Function ( code. render) , staticRenderFns : code. staticRenderFns. map ( fn => new Function ( fn) ) }
}
function render ( ) { with ( this ) { return _c ( 'div' , { attrs : { "id" : "app" } } , [ _c ( 'p' , [ _v ( _s ( message) ) ] ) , _c ( 'button' , { on : { "click" : handleClick} } , [ _v ( "Click" ) ] ) ] ) }
}
五、组件系统与生命周期
5.1 组件初始化流程
initMixin VueComponent patch 合并选项 初始化生命周期 初始化事件 初始化渲染 创建$el initMixin VueComponent patch
5.2 生命周期源码触发点
Vue . prototype. _init = function ( options ) { initLifecycle ( vm) initEvents ( vm) initRender ( vm) callHook ( vm, 'beforeCreate' ) initInjections ( vm) initState ( vm) initProvide ( vm) callHook ( vm, 'created' ) if ( vm. $options. el) { vm. $mount ( vm. $options. el) }
}
六、异步更新队列与性能优化
6.1 更新队列流程图
数据变更
触发setter
将Watcher推入队列
nextTick后执行
执行Watcher.run
触发组件更新
6.2 核心实现代码
const queue = [ ]
let waiting = false function flushSchedulerQueue ( ) { queue. sort ( ( a, b ) => a. id - b. id) for ( let i = 0 ; i < queue. length; i++ ) { const watcher = queue[ i] watcher. run ( ) } resetSchedulerState ( )
} export function queueWatcher ( watcher ) { if ( ! queue. includes ( watcher) ) { queue. push ( watcher) } if ( ! waiting) { nextTick ( flushSchedulerQueue) waiting = true }
}
七、Vue 3 新特性源码对比
7.1 响应式系统升级
function reactive ( target ) { return new Proxy ( target, { get ( target, key, receiver) { track ( target, key) return Reflect. get ( ... arguments) } , set ( target, key, value, receiver) { Reflect. set ( ... arguments) trigger ( target, key) } } )
}
7.2 编译优化对比
优化点 Vue 2 Vue 3 静态提升 无 标记静态节点 补丁标志 全量Diff 动态节点追踪 缓存事件 每次渲染重新创建 缓存事件处理函数
八、手写迷你Vue框架实战
8.1 核心实现代码
class MyVue { constructor ( options ) { this . $options = optionsthis . _data = options. data ( ) new Observer ( this . _data) new Compiler ( options. el, this ) }
} class Observer { constructor ( data ) { this . walk ( data) } walk ( data ) { Object. keys ( data) . forEach ( key => { defineReactive ( data, key, data[ key] ) } ) }
} function defineReactive ( obj, key, val ) { const dep = new Dep ( ) Object. defineProperty ( obj, key, { get ( ) { Dep. target && dep. addSub ( Dep. target) return val} , set ( newVal) { val = newValdep. notify ( ) } } )
}
总结
本文从Vue源码层面深入解析了响应式系统、虚拟DOM、模板编译等核心模块的实现原理。建议通过以下方式进一步学习:
使用Vue官方调试版本进行断点调试 参与Vue源码GitHub Issue讨论 对比不同版本实现差异