Skip to content

Vue 源码学习

源码

https://vscode.dev/github/vuejs/vue

从正式发布的第一个版本读 0.01-0.03

v0.7.0 最低版本

js
new Vue(options)
  function ViewModel(options)
    new Compiler(this, options)

this 表示 vm instance,

核心流程在 compiler.js

Compiler 构造函数,原型扩展方法

有很多连续赋值

初始化元素:setupElement 确定 el,深拷贝 template 并返回 el

partial 类似 slot?

学习方法

源码断点

js
    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)

Vue2.0源码分析:Rollup构建,目录设计和整体流程

初始化主线逻辑一目了然

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 区分。

第 97 题:React 和 Vue 的 diff 时间复杂度从 O(n^3) 优化到 O(n) ,那么 O(n^3) 和 O(n) 是如何计算出来的? · Issue #151 · Advanced-Frontend/Daily-Interview-Question

传统diff、react优化diff、vue优化diff - 简书

解析vue2.0的diff算法 · Issue #2 · aooy/blog

虚拟 DOM 到底是什么?

关于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官方社区