生命周期
正常的生命周期
const onBeforeMount = createHook ( 'bm' )
const onMounted = createHook ( 'm' )
const onBeforeUpdate = createHook ( 'bu' )
const onUpdated = createHook ( 'u' )
const onBeforeUnmount = createHook ( 'bum' )
const onUnmounted = createHook ( 'um' )
const onRenderTriggered = createHook ( 'rtg' )
const onRenderTracked = createHook ( 'rtc' )
const onErrorCaptured = ( hook, target = currentInstance ) => {
injectHook ( 'ec' , hook, target)
}
function createHook ( lifecycle ) {
return function ( hook, target = currentInstance ) {
injectHook ( lifecycle, hook, target)
}
}
function injectHook ( type, hook, target = currentInstance, prepend = false ) {
const hooks = target[ type] || ( target[ type] = [ ] )
const wrappedHook = hook. __weh || ( hook. __weh = ( ... args) => {
if ( target. isUnmounted) return
pauseTracking ( )
setCurrentInstance ( target)
const res = callWithAsyncErrorHandling ( hook, target, type, args)
setCurrnetInstance ( null )
resetTracking ( )
return res
} )
if ( prepend) {
hooks. unshift ( wrappedHook)
} else {
hook. push ( wrappedHook)
}
}
const setupRenderEffect = ( instance, initialVNode, container, anchor, parentSuspense, isSVG, optimized ) => {
instance. update = effect ( function componentEffect ( ) {
if ( ! instance. isMounted) {
const { bm, m } = instance
const subTree = ( instance. subTree = renderComponentRoot ( instance) )
if ( bm) {
invokeArrayFus ( bm)
}
patch ( null , subTree, container, anchor, instance, parentSuspense, isSVG)
initialVNode. el = subTree. el
if ( m) {
queuePostRenderEffect ( m, parentSuspense)
}
instance. isMounted = true
}
else {
let { next, vnode, bu, u } = instance
if ( next) {
updateComponentPreRender ( instance, next, optimized)
} else {
next = vnode
}
const nextTree = renderComponentRoot ( instance)
const prevTree = instance. subTree
instance. subTree = nextTREE
if ( bu) {
invokeArrayFns ( bu)
}
patch ( prevTree, nextTree,
hostParentNode ( prevTree. el) ,
getNextHostNode ( prevTree) , instance, parentSuspense, isSVG)
next. el = nextTree. el
if ( u) {
queuePostRenderEffect ( u, parentSuspense)
}
}
} , prodEffectOptions)
}
const unmountComponent = ( instance, parentSuspense, doRemove ) => {
const { bum, effects, update, subTree, um } = instance
if ( bum) {
invokeArrayFns ( bum)
}
if ( effects) {
for ( let i = 0 ; i < effects. length; i++ ) {
stop ( effects[ i] )
}
}
if ( update) {
stop ( update)
unmount ( subTree, instance, parentSuspense, doRemove)
}
if ( um) {
queuePostRenderEffect ( um, parentSuspense)
}
}
捕获后代组件错误的生命周期
function handleError ( err, instance, type ) {
const contextVNode = instance ? instance. vnode : null
if ( instance) {
let cur = instance. parent
const exposedInstance = instance. proxy
const errorInfo = ( process. env. NODE_ENV !== 'production' ) ? ErrorTypeStrings[ type] : type
while ( cur) {
const errorCapturedHooks = cur. ec
if ( errorCapturedHooks) {
for ( let i = 0 ; i < errorCapturedHooks. length; i++ ) {
if ( errorCapturedHooks[ i] ( err, exposedInstance, errorInfo) ) return
}
}
cur = cur. parent
}
}
logError ( err, type, contextVNode)
}
开发环境下调试的生命周期
function createDevEffectOptions ( instance ) {
return {
scheduler : queueJob,
onTrack : instance. rtc ? e => invokeArrayFns ( instance. rtc, e) : void 0 ,
onTrigger : instance. rtg ? e => invokeArrayFns ( instance. rtg, e) : void 0
}
}
function track ( target, type, key ) {
if ( ! dep. has ( activeEffect) ) {
dep. add ( activeEffect)
activeEffect. deps. push ( dep)
if ( ( process. env. NODE_ENV !== 'production' ) && activeEffect. options. onTrack) {
activeEffect. options. onTrack ( {
effect : activeEffect,
target,
type,
key
} )
}
}
}
function trigger ( target, type, key, newValue ) {
const run = ( effect ) => {
if ( ( process. env. NODE_ENV !== 'production' ) && effect. options. onTrigger) {
effect. options. onTrigger ( {
effect,
target,
key,
type,
newValue,
oldValue,
oldTarget
} )
}
if ( effect. options. scheduler) {
effect. options. scheduler ( effect)
} else {
effect ( )
}
}
effects. forEach ( run)
}