Vue 源码学习
源码
https://vscode.dev/github/vuejs/vue
从正式发布的第一个版本读 0.01-0.03
v0.7.0 最低版本
new Vue(options)
function ViewModel(options)
new Compiler(this, options)
this 表示 vm instance,
核心流程在 compiler.js
Compiler 构造函数,原型扩展方法
有很多连续赋值
初始化元素:setupElement 确定 el,深拷贝 template 并返回 el
partial 类似 slot?
学习方法
源码断点
resolve: {
alias: {
vue$: 'vue/dist/vue.esm.js',
},
},
Object.defineProperty()
可以为 object 新增或修改属性
通过全局方法Vue.use()
使用插件
'component', 'directive', 'filter'
Vue 构造函数传递
initMixin 原型继承来扩展
let uid = 0 vm._uid = uid++
vm this
unwatch 闭包
data 代理,对外接口,劫持 set 警告 prop 只读
for 优化 let i = 0, l = cbs.length
事件注册,可接收数组 (vm._events[event] || (vm._events[event] = [])).push(fn)
初始化主线逻辑一目了然
Vue 实例挂载的实现 | Vue.js 技术揭秘
vnode create diff patch
isDef isUndef helper 是否定义
observe
注意,是个动词 响应式原理的入口,根据数据类型处理观察逻辑
Observer 类中的 defineReactive 方法封装了 Object.defineProperty 对象属性观察者,收集依赖、派发更新
数据是被观察者,setter 订阅的 watcher 触发 update
Dep 是对 Watcher 的管理
walk/observeArray
https://www.how-to-vue.com/vue/reactivity/observer.html#the-observe-method
初始化、更新两个阶段,diff patch 发生在更新时
Watcher
用于执行更新渲染。该组件将有一个渲染观察器。我们常说的collection依赖就是collection watcher
Watcher负责收集依赖,清除依赖和通知依赖
虚拟 dom 与实际 dom 解耦,能运行于非浏览器,RN/Weex 原因
diff策略 React用 三大策略 将O(n^3)复杂度 转化为 O(n)复杂度 策略一(tree diff): Web UI中DOM节点跨层级的移动操作特别少,可以忽略不计。 策略二(component diff): 拥有相同类的两个组件 生成相似的树形结构, 拥有不同类的两个组件 生成不同的树形结构。 策略三(element diff): 对于同一层级的一组子节点,通过唯一 key 区分。
传统diff、react优化diff、vue优化diff - 简书
解析vue2.0的diff算法 · Issue #2 · aooy/blog
关于vue的diff算法 · Issue #7 · YangPengFe1/yunydemo
blog/vue中的diff算法实现[writting..].md at master · isaaxite/blog
learnVue/VirtualDOM与diff(Vue实现).MarkDown at master · answershuto/learnVue
Vue2.x源码解析系列十:Patch和Diff 算法 · Issue #33 · lihongxun945/myblog人
数组观察,改写内部指针 if (Array.isArray(value)) { if (hasProto) { protoAugment(value, arrayMethods)
src/core/observer/array.js
data msg ob id subs
dep
Dep.target 目标 watcher,单例,是一时间只能执行一个 watcher 是什么
Dep.target = null const targetStack = []
obj walk for keys
mountComponent new Watcher(vm, updateComponent
if (isRenderWatcher) { vm._watcher = this; } vm._watchers.push(this); watcher 将自身添加 vm
更新组件方法作为 getter
数据结构 quene
flushSchedulerQueue
一个页面有多个组件,数据变化了,要通知哪个组件更新?挂载某个组件时,作为此时唯一 watcher,访问到某个属性,则将 watcher 添加对属性订阅者
staticRenderFns
字符串数组,render 时将静态节点(后续不再更新)存起来,执行转成函数
渲染优化
Dep 和 Observer 的关系是 Observer 监听整个数据,遍历数据的每个属性,给每个属性绑定 defineReactive 方法,劫持 getter 和 setter,getter 时将依赖(dep.depend)插入 Dep 类,通知所有watcher s 在 setter 时更新(dep.notify)
vue源码解读(一)Observer/Dep/Watcher是如何实现数据绑定的 - moon3 - 博客园
Touch and take you to understand Vue's responsive principle_javascript_EUV-DevPress官方社区