anchors
题外
- 组件在render的时候就调用了那些响应式属性的getter了,也就收集了依赖.
- 哪个vm调用update,就是activeInstance, vm.$vnode是占位vnode, vm._vnode的渲染vnode
- new组件的Vue之前做option合并, 原型继承返回新constructor
- merge(Vue.options, vm.options)
- 声明的component都是Vue的孙子构造函数, 在什么时候new呢?
createComponentInstanceForVnode
里执行了return new vnode.componentOptions.Ctor(options)
- 挂载点就是父vm里template出现的位置
render组件时创建vnode是个深度遍历过程
创建组件占位符vnode
|
|
关联父子关系vnode和vm
|
|
|
|
子组件递归patch相关代码
|
|
merge-option
extend,mixin都会调用merge options
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950function mergeOptions (parent,child,vm) {if (process.env.NODE_ENV !== 'production') {checkComponents(child);}if (typeof child === 'function') {child = child.options;}normalizeProps(child, vm);normalizeInject(child, vm);normalizeDirectives(child);// Apply extends and mixins on the child options,// but only if it is a raw options object that isn't// the result of another mergeOptions call.// Only merged options has the _base property.if (!child._base) {if (child.extends) {parent = mergeOptions(parent, child.extends, vm);}if (child.mixins) {for (var i = 0, l = child.mixins.length; i < l; i++) {parent = mergeOptions(parent, child.mixins[i], vm);}}}var options = {};var key;for (key in parent) {mergeField(key);}for (key in child) {if (!hasOwn(parent, key)) {mergeField(key);}}function mergeField (key) {var strat = strats[key] || defaultStrat;// 合并策略,覆盖执行还是叠加执行options[key] = strat(parent[key], child[key], vm, key);}return options}子组件的merge option
- extend时合并了选项后执行initInternalComponent, 追加几个子组件选项
- 执行 new vnode.componentOptions.Ctor(options) 接着执行 this._init(options),因为 options._isComponent 为 true,那么合并 options 的过程走到了 initInternalComponent(vm, options) 逻辑
- 子组件的option通过原型继承父组件的options
|
|
|
|
生命周期
- beforeCreate
vue-router 和 vuex
都混合了beforeCreate做一些处理 - 做初始化, 响应式
- created 可以访问 props、data
- beforeMount 先父后子
- mounted 先子后父. 根组件在
mountComponent
调用,子组件在componentVNodeHooks.insert
中调用 - beforeUpdate 渲染watcher
非首次patch
vm._isMounted
才调用 - updated
flushSchedulerQueue
里满足if (vm._watcher === watcher && vm._isMounted)
调用 - beforeDestroy 先父后子
- destroyed 先子后父
异步组件
- 异步组件第一次patch后, 渲染了个注释节点.
- render时通过
resolveAsyncComponent
,设置异步回调resolve(模板加载后, extend constructor, 通过forceUpdate重新渲染.) - 通过require引入的组件直接注入resolve, import引入的在then里注入
- render时通过
- 高级异步组件通过
resolveAsyncComponent
在delay后forceUpdateloading
组件, 加载超过timeout则返回factory.errorComp
组件 - 二次渲染过程和普通组件一样
|
|
|
|
|
|
|
|