源码内容
config
optionMergeStrategies
silent: false
productionTip: true
devtools: true
performance: false
errorHandler: null
warnHandler: null
ignoredElements: []
keyCodes: {}
isReservedTag: ƒ (a, b, c)
isReservedAttr: ƒ (a, b, c)
isUnknownElement: ƒ (a, b, c)
getTagNamespace: ƒ noop(a, b, c)
parsePlatformTagName: ƒ (_)
mustUseProp: ƒ (a, b, c)
_lifecycleHooks: (10) ["beforeCreate", "created", "beforeMount", "mounted", "beforeUpdate", "updated", "beforeDestroy", "destroyed", "activated", "deactivated"]
warn、tip、formatComponentName、repeat、generateComponentTrace
判断浏览器环境
var inBrowser = typeof window !== 'undefined';
var UA = inBrowser && window.navigator.userAgent.toLowerCase();
var isIE = UA && /msie|trident/.test(UA);
var isIE9 = UA && UA.indexOf('msie 9.0') > 0;
var isEdge = UA && UA.indexOf('edge/') > 0;
var isAndroid = UA && UA.indexOf('android') > 0;
var isIOS = UA && /iphone|ipad|ipod|ios/.test(UA);
var isChrome = UA && /chrome\/\d+/.test(UA) && !isEdge;
new _Set()
has: ƒ has()
add: ƒ add()
delete: ƒ delete()
clear: ƒ clear()
entries: ƒ entries()
forEach: ƒ forEach()
values: ƒ values()
keys: ƒ values()
new Dep()
id: 2
subs: []
__proto__:
addSub: ƒ addSub(sub)
removeSub: ƒ removeSub(sub)
depend: ƒ depend()
notify: ƒ notify()
strats = config.optionMergeStrategies
propsData: ƒ (parent, child, vm, key)
el: ƒ (parent, child, vm, key)
data: ƒ ( parentVal, childVal, vm )
beforeCreate: ƒ mergeHook( parentVal, childVal )
created: ƒ mergeHook( parentVal, childVal )
beforeMount: ƒ mergeHook( parentVal, childVal )
mounted: ƒ mergeHook( parentVal, childVal )
beforeUpdate: ƒ mergeHook( parentVal, childVal )
updated: ƒ mergeHook( parentVal, childVal )
beforeDestroy: ƒ mergeHook( parentVal, childVal )
destroyed: ƒ mergeHook( parentVal, childVal )
activated: ƒ mergeHook( parentVal, childVal )
deactivated: ƒ mergeHook( parentVal, childVal )
components: ƒ mergeAssets(parentVal, childVal)
directives: ƒ mergeAssets(parentVal, childVal)
filters: ƒ mergeAssets(parentVal, childVal)
watch: ƒ (parentVal, childVal)
computed: ƒ (parentVal, childVal)
inject: ƒ (parentVal, childVal)
methods: ƒ (parentVal, childVal)
props: ƒ (parentVal, childVal)
provide: ƒ mergeDataOrFn( parentVal, childVal, vm )
perf = inBrowser && window.performance;
VNode
tag: undefined
data: undefined
children: undefined
text: undefined
elm: undefined
ns: undefined
context: undefined
functionalContext: undefined
key: undefined
componentOptions: undefined
componentInstance: undefined
parent: undefined
raw: false
isStatic: false
isRootInsert: true
isComment: false
isCloned: false
isOnce: false
asyncFactory: undefined
asyncMeta: undefined
isAsyncPlaceholder: false
Watcher
componentVNodeHooks
init
prepatch
insert
destroy
initMixin
_init
initLifecycle(vm);
initEvents(vm);
initRender(vm);
callHook(vm, 'beforeCreate');
initInjections(vm);
initState(vm);
initProvide(vm);
callHook(vm, 'created');
...
vm.$mount(vm.$options.el);
stateMixin
$data、$props、$set、$delete 、$watch
eventsMixin
$on、$once、$off、$emit
lifecycleMixin
_update、$forceUpdate、$destroy
renderMixin
$nextTick、_render
Vue.prototype._o = markOnce;
Vue.prototype._n = toNumber;
Vue.prototype._s = toString;
Vue.prototype._l = renderList;
Vue.prototype._t = renderSlot;
Vue.prototype._q = looseEqual;
Vue.prototype._i = looseIndexOf;
Vue.prototype._m = renderStatic;
Vue.prototype._f = resolveFilter;
Vue.prototype._k = checkKeyCodes;
Vue.prototype._b = bindObjectProps;
Vue.prototype._v = createTextVNode;
Vue.prototype._e = createEmptyVNode;
Vue.prototype._u = resolveScopedSlots;
Vue.prototype._g = bindObjectListeners;
KeepAlive
name: "keep-alive"
abstract: true
props: {include: Array(3), exclude: Array(3)}
created: ƒ created()
destroyed: ƒ destroyed()
watch: {include: ƒ, exclude: ƒ}
render: ƒ render()
builtInComponents = {
KeepAlive: KeepAlive
}
initGlobalAPI
initUse(Vue);
initMixin$1(Vue);
initExtend(Vue);
initAssetRegisters(Vue);
nodeOps
createElement: ƒ createElement$1(tagName, vnode)
createElementNS: ƒ createElementNS(namespace, tagName)
createTextNode: ƒ createTextNode(text)
createComment: ƒ createComment(text)
insertBefore: ƒ insertBefore(parentNode, newNode, referenceNode)
removeChild: ƒ removeChild(node, child)
appendChild: ƒ appendChild(node, child)
parentNode: ƒ parentNode(node)
nextSibling: ƒ nextSibling(node)
tagName: ƒ tagName(node)
setTextContent: ƒ setTextContent(node, text)
setAttribute: ƒ setAttribute(node, key, val)
ref
create: ƒ create(_, vnode)
update: ƒ update(oldVnode, vnode)
destroy: ƒ destroy(vnode)
directives
create: ƒ updateDirectives(oldVnode, vnode)
update: ƒ updateDirectives(oldVnode, vnode)
destroy: ƒ unbindDirectives(vnode)
baseModules = [ref, directives]
attrs = {
create: updateAttrs,
update: updateAttrs
}
klass = {
create: updateClass,
update: updateClass
}
events = {
create: updateDOMListeners,
update: updateDOMListeners
}
domProps = {
create: updateDOMProps,
update: updateDOMProps
}
style = {
create: updateStyle,
update: updateStyle
}
platformModules = [attrs, klass, events, domProps, style, transition]
modules = platformModules.concat(baseModules)
patch = createPatchFunction({
nodeOps: nodeOps,
modules: modules
})
transitionProps = {
name: String,
appear: Boolean,
css: Boolean,
mode: String,
type: String,
enterClass: String,
leaveClass: String,
enterToClass: String,
leaveToClass: String,
enterActiveClass: String,
leaveActiveClass: String,
appearClass: String,
appearActiveClass: String,
appearToClass: String,
duration: [Number, String, Object]
}
patch
$mount
compile 编译
compileToFunctions
|-- parse 解析
|-- optimize 优化
|-- generate 生成
概念
UI = render(state)
state 和 UI 都是用户定的,不变的是这个 render() ==> vue
变化侦测:追踪状态
Angular 中是通过`脏值检查流程`来实现变化侦测
在 React 是通过`对比虚拟DOM`来实现变化侦测
Object.defineProperty
实现数据的读写观察
Observer
Observer类会通过递归的方式把一个对象的所有属性都转化成可观测对象
在 getter 中收集依赖,在 setter 中通知依赖更新
依赖管理器 Dep
Watcher
Array 拦截器
虚拟 DOM
用一个JS对象来描述一个DOM节点
VNode 类:
注释节点
文本节点
元素节点
组件节点
函数式组件节点
克隆节点
DOM-Diff ===> patch
创建节点,删除节点和更新节点
render
- 抽象语法数(AbstractSyntaxTree,AST)
- 模板解析阶段:将一堆模板字符串用正则等方式解析成抽象语法树AST;
- 优化阶段:遍历AST,找出其中的静态节点,并打上标记;
- 代码生成阶段:将AST转换成渲染函数;
- 优化
在AST中找出所有静态节点并打上标记;
在AST中找出所有静态根节点并打上标记;
生命周期流程
- new Vue()
- vm_init
-> 初始化 lifecycle
-> 初始化 Events
-> 初始化 Render
-> 调用钩子 beforeCreate
-> 初始化 State
-> 调用钩子 created-> 依赖收集 (props\data\computed\watch\methods)
挂载组件 vm.$mount - vm.$mount
-> compile()
-> 调用钩子 beforeMount
-> new Watcher
-> 调用钩子 mount-> vm_render createElement -> VNode Tree -> vm_update 渲染真实DOM
- compile()
-> parse -> AST
-> optimize 优化
-> generate 生成 - render function
– touch –> getter\setter –> watcher – > update
– VDOM Tree - patch()
-> patchVnode
-> updateChikldren - Real Dom