refactor: remove null comparisons

This commit is contained in:
Evan You 2020-03-18 18:14:51 -04:00
parent 811f28a7d1
commit ba9a91c48c
18 changed files with 104 additions and 119 deletions

View File

@ -545,7 +545,7 @@ function parseAttribute(
{ {
const pattern = /["'<]/g const pattern = /["'<]/g
let m: RegExpExecArray | null let m: RegExpExecArray | null
while ((m = pattern.exec(name)) !== null) { while ((m = pattern.exec(name))) {
emitError( emitError(
context, context,
ErrorCodes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME, ErrorCodes.UNEXPECTED_CHARACTER_IN_ATTRIBUTE_NAME,
@ -696,7 +696,7 @@ function parseAttributeValue(
} }
const unexpectedChars = /["'<=`]/g const unexpectedChars = /["'<=`]/g
let m: RegExpExecArray | null let m: RegExpExecArray | null
while ((m = unexpectedChars.exec(match[0])) !== null) { while ((m = unexpectedChars.exec(match[0]))) {
emitError( emitError(
context, context,
ErrorCodes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE, ErrorCodes.UNEXPECTED_CHARACTER_IN_UNQUOTED_ATTRIBUTE_VALUE,

View File

@ -46,7 +46,7 @@ export let activeEffect: ReactiveEffect | undefined
export const ITERATE_KEY = Symbol('iterate') export const ITERATE_KEY = Symbol('iterate')
export function isEffect(fn: any): fn is ReactiveEffect { export function isEffect(fn: any): fn is ReactiveEffect {
return fn != null && fn._isEffect === true return fn && fn._isEffect === true
} }
export function effect<T = any>( export function effect<T = any>(

View File

@ -229,7 +229,7 @@ function doWatch(
scheduler = invoke scheduler = invoke
} else if (flush === 'pre') { } else if (flush === 'pre') {
scheduler = job => { scheduler = job => {
if (!instance || instance.vnode.el != null) { if (!instance || instance.isMounted) {
queueJob(job) queueJob(job)
} else { } else {
// with 'pre' option, the first call must happen before // with 'pre' option, the first call must happen before

View File

@ -98,7 +98,7 @@ export function resolveProps(
rawProps: Data | null, rawProps: Data | null,
_options: ComponentPropsOptions | void _options: ComponentPropsOptions | void
) { ) {
const hasDeclaredProps = _options != null const hasDeclaredProps = !!_options
if (!rawProps && !hasDeclaredProps) { if (!rawProps && !hasDeclaredProps) {
return return
} }
@ -122,7 +122,7 @@ export function resolveProps(
// allow mutation of propsProxy (which is readonly by default) // allow mutation of propsProxy (which is readonly by default)
unlock() unlock()
if (rawProps != null) { if (rawProps) {
for (const key in rawProps) { for (const key in rawProps) {
const value = rawProps[key] const value = rawProps[key]
// key, ref are reserved and never passed down // key, ref are reserved and never passed down
@ -186,10 +186,7 @@ export function resolveProps(
// in case of dynamic props, check if we need to delete keys from // in case of dynamic props, check if we need to delete keys from
// the props proxy // the props proxy
const { patchFlag } = instance.vnode const { patchFlag } = instance.vnode
if ( if (propsProxy && (patchFlag === 0 || patchFlag & PatchFlags.FULL_PROPS)) {
propsProxy !== null &&
(patchFlag === 0 || patchFlag & PatchFlags.FULL_PROPS)
) {
const rawInitialProps = toRaw(propsProxy) const rawInitialProps = toRaw(propsProxy)
for (const key in rawInitialProps) { for (const key in rawInitialProps) {
if (!hasOwn(props, key)) { if (!hasOwn(props, key)) {
@ -250,7 +247,7 @@ function normalizePropsOptions(
const opt = raw[key] const opt = raw[key]
const prop: NormalizedProp = (options[normalizedKey] = const prop: NormalizedProp = (options[normalizedKey] =
isArray(opt) || isFunction(opt) ? { type: opt } : opt) isArray(opt) || isFunction(opt) ? { type: opt } : opt)
if (prop != null) { if (prop) {
const booleanIndex = getTypeIndex(Boolean, prop.type) const booleanIndex = getTypeIndex(Boolean, prop.type)
const stringIndex = getTypeIndex(String, prop.type) const stringIndex = getTypeIndex(String, prop.type)
prop[BooleanFlags.shouldCast] = booleanIndex > -1 prop[BooleanFlags.shouldCast] = booleanIndex > -1

View File

@ -109,7 +109,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
} else if (renderContext !== EMPTY_OBJ && hasOwn(renderContext, key)) { } else if (renderContext !== EMPTY_OBJ && hasOwn(renderContext, key)) {
accessCache![key] = AccessTypes.CONTEXT accessCache![key] = AccessTypes.CONTEXT
return renderContext[key] return renderContext[key]
} else if (type.props != null) { } else if (type.props) {
// only cache other properties when instance has declared (this stable) // only cache other properties when instance has declared (this stable)
// props // props
if (hasOwn(props, key)) { if (hasOwn(props, key)) {
@ -125,20 +125,20 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
// public $xxx properties & user-attached properties (sink) // public $xxx properties & user-attached properties (sink)
const publicGetter = publicPropertiesMap[key] const publicGetter = publicPropertiesMap[key]
let cssModule let cssModule
if (publicGetter != null) { if (publicGetter) {
if (__DEV__ && key === '$attrs') { if (__DEV__ && key === '$attrs') {
markAttrsAccessed() markAttrsAccessed()
} }
return publicGetter(target) return publicGetter(target)
} else if ( } else if (
__BUNDLER__ && __BUNDLER__ &&
(cssModule = type.__cssModules) != null && (cssModule = type.__cssModules) &&
(cssModule = cssModule[key]) (cssModule = cssModule[key])
) { ) {
return cssModule return cssModule
} else if (hasOwn(sink, key)) { } else if (hasOwn(sink, key)) {
return sink[key] return sink[key]
} else if (__DEV__ && currentRenderingInstance != null) { } else if (__DEV__ && currentRenderingInstance) {
warn( warn(
`Property ${JSON.stringify(key)} was accessed during render ` + `Property ${JSON.stringify(key)} was accessed during render ` +
`but is not defined on instance.` `but is not defined on instance.`
@ -152,7 +152,7 @@ export const PublicInstanceProxyHandlers: ProxyHandler<any> = {
accessCache![key] !== undefined || accessCache![key] !== undefined ||
(data !== EMPTY_OBJ && hasOwn(data, key)) || (data !== EMPTY_OBJ && hasOwn(data, key)) ||
hasOwn(renderContext, key) || hasOwn(renderContext, key) ||
(type.props != null && hasOwn(type.props, key)) || (type.props && hasOwn(type.props, key)) ||
hasOwn(publicPropertiesMap, key) || hasOwn(publicPropertiesMap, key) ||
hasOwn(sink, key) hasOwn(sink, key)
) )

View File

@ -90,7 +90,7 @@ export function renderComponentRoot(
result = cloneVNode(result, fallthroughAttrs) result = cloneVNode(result, fallthroughAttrs)
// If the child root node is a compiler optimized vnode, make sure it // If the child root node is a compiler optimized vnode, make sure it
// force update full props to account for the merged attrs. // force update full props to account for the merged attrs.
if (result.dynamicChildren !== null) { if (result.dynamicChildren) {
result.patchFlag |= PatchFlags.FULL_PROPS result.patchFlag |= PatchFlags.FULL_PROPS
} }
} else if (__DEV__ && !accessedAttrs && result.type !== Comment) { } else if (__DEV__ && !accessedAttrs && result.type !== Comment) {
@ -109,7 +109,7 @@ export function renderComponentRoot(
result = cloneVNode(result, { [parentScopeId]: '' }) result = cloneVNode(result, { [parentScopeId]: '' })
} }
// inherit directives // inherit directives
if (vnode.dirs != null) { if (vnode.dirs) {
if (__DEV__ && !isElementRoot(result)) { if (__DEV__ && !isElementRoot(result)) {
warn( warn(
`Runtime directive used on component with non-element root node. ` + `Runtime directive used on component with non-element root node. ` +
@ -119,7 +119,7 @@ export function renderComponentRoot(
result.dirs = vnode.dirs result.dirs = vnode.dirs
} }
// inherit transition data // inherit transition data
if (vnode.transition != null) { if (vnode.transition) {
if (__DEV__ && !isElementRoot(result)) { if (__DEV__ && !isElementRoot(result)) {
warn( warn(
`Component inside <Transition> renders non-element root node ` + `Component inside <Transition> renders non-element root node ` +
@ -185,7 +185,7 @@ export function shouldUpdateComponent(
} }
// force child update on runtime directive usage on component vnode. // force child update on runtime directive usage on component vnode.
if (nextVNode.dirs != null) { if (nextVNode.dirs) {
return true return true
} }
@ -218,18 +218,18 @@ export function shouldUpdateComponent(
} else if (!optimized) { } else if (!optimized) {
// this path is only taken by manually written render functions // this path is only taken by manually written render functions
// so presence of any children leads to a forced update // so presence of any children leads to a forced update
if (prevChildren != null || nextChildren != null) { if (prevChildren || nextChildren) {
if (nextChildren == null || !(nextChildren as any).$stable) { if (!nextChildren || !(nextChildren as any).$stable) {
return true return true
} }
} }
if (prevProps === nextProps) { if (prevProps === nextProps) {
return false return false
} }
if (prevProps === null) { if (!prevProps) {
return nextProps !== null return !!nextProps
} }
if (nextProps === null) { if (!nextProps) {
return true return true
} }
return hasPropsChanged(prevProps, nextProps) return hasPropsChanged(prevProps, nextProps)

View File

@ -40,7 +40,7 @@ const normalizeSlot = (
ctx: ComponentInternalInstance | null | undefined ctx: ComponentInternalInstance | null | undefined
): Slot => ): Slot =>
withCtx((props: any) => { withCtx((props: any) => {
if (__DEV__ && currentInstance != null) { if (__DEV__ && currentInstance) {
warn( warn(
`Slot "${key}" invoked outside of the render function: ` + `Slot "${key}" invoked outside of the render function: ` +
`this will not track dependencies used in the slot. ` + `this will not track dependencies used in the slot. ` +
@ -80,7 +80,7 @@ export function resolveSlots(
} }
} }
} }
} else if (children !== null) { } else if (children) {
// non slot object children (direct value) passed to a component // non slot object children (direct value) passed to a component
if (__DEV__ && !isKeepAlive(instance.vnode)) { if (__DEV__ && !isKeepAlive(instance.vnode)) {
warn( warn(

View File

@ -85,7 +85,7 @@ const KeepAliveImpl = {
queuePostRenderEffect(() => { queuePostRenderEffect(() => {
const component = vnode.component! const component = vnode.component!
component.isDeactivated = false component.isDeactivated = false
if (component.a !== null) { if (component.a) {
invokeHooks(component.a) invokeHooks(component.a)
} }
}, parentSuspense) }, parentSuspense)
@ -95,7 +95,7 @@ const KeepAliveImpl = {
move(vnode, storageContainer, null, MoveType.LEAVE, parentSuspense) move(vnode, storageContainer, null, MoveType.LEAVE, parentSuspense)
queuePostRenderEffect(() => { queuePostRenderEffect(() => {
const component = vnode.component! const component = vnode.component!
if (component.da !== null) { if (component.da) {
invokeHooks(component.da) invokeHooks(component.da)
} }
component.isDeactivated = true component.isDeactivated = true

View File

@ -44,7 +44,7 @@ export const PortalImpl = {
const target = (n2.target = isString(targetSelector) const target = (n2.target = isString(targetSelector)
? querySelector!(targetSelector) ? querySelector!(targetSelector)
: targetSelector) : targetSelector)
if (target != null) { if (target) {
if (shapeFlag & ShapeFlags.TEXT_CHILDREN) { if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
setElementText(target, children as string) setElementText(target, children as string)
} else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) { } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
@ -93,7 +93,7 @@ export const PortalImpl = {
const nextTarget = (n2.target = isString(targetSelector) const nextTarget = (n2.target = isString(targetSelector)
? querySelector!(targetSelector) ? querySelector!(targetSelector)
: targetSelector) : targetSelector)
if (nextTarget != null) { if (nextTarget) {
// move content // move content
if (shapeFlag & ShapeFlags.TEXT_CHILDREN) { if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
setElementText(target, '') setElementText(target, '')

View File

@ -536,7 +536,7 @@ export function queueEffectWithSuspense(
fn: Function | Function[], fn: Function | Function[],
suspense: SuspenseBoundary | null suspense: SuspenseBoundary | null
): void { ): void {
if (suspense !== null && !suspense.isResolved) { if (suspense && !suspense.isResolved) {
if (isArray(fn)) { if (isArray(fn)) {
suspense.effects.push(...fn) suspense.effects.push(...fn)
} else { } else {

View File

@ -79,7 +79,7 @@ export function callWithAsyncErrorHandling(
): any[] { ): any[] {
if (isFunction(fn)) { if (isFunction(fn)) {
const res = callWithErrorHandling(fn, instance, type, args) const res = callWithErrorHandling(fn, instance, type, args)
if (res != null && !res._isVue && isPromise(res)) { if (res && !res._isVue && isPromise(res)) {
res.catch(err => { res.catch(err => {
handleError(err, instance, type) handleError(err, instance, type)
}) })
@ -108,7 +108,7 @@ export function handleError(
const errorInfo = __DEV__ ? ErrorTypeStrings[type] : type const errorInfo = __DEV__ ? ErrorTypeStrings[type] : type
while (cur) { while (cur) {
const errorCapturedHooks = cur.ec const errorCapturedHooks = cur.ec
if (errorCapturedHooks !== null) { if (errorCapturedHooks) {
for (let i = 0; i < errorCapturedHooks.length; i++) { for (let i = 0; i < errorCapturedHooks.length; i++) {
if (errorCapturedHooks[i](err, exposedInstance, errorInfo)) { if (errorCapturedHooks[i](err, exposedInstance, errorInfo)) {
return return

View File

@ -199,12 +199,12 @@ export function createHydrationFunctions(
parentSuspense: SuspenseBoundary | null, parentSuspense: SuspenseBoundary | null,
optimized: boolean optimized: boolean
) => { ) => {
optimized = optimized || vnode.dynamicChildren !== null optimized = optimized || !!vnode.dynamicChildren
const { props, patchFlag, shapeFlag, dirs } = vnode const { props, patchFlag, shapeFlag, dirs } = vnode
// skip props & children if this is hoisted static nodes // skip props & children if this is hoisted static nodes
if (patchFlag !== PatchFlags.HOISTED) { if (patchFlag !== PatchFlags.HOISTED) {
// props // props
if (props !== null) { if (props) {
if ( if (
!optimized || !optimized ||
(patchFlag & PatchFlags.FULL_PROPS || (patchFlag & PatchFlags.FULL_PROPS ||
@ -215,7 +215,7 @@ export function createHydrationFunctions(
patchProp(el, key, null, props[key]) patchProp(el, key, null, props[key])
} }
} }
} else if (props.onClick != null) { } else if (props.onClick) {
// Fast path for click listeners (which is most often) to avoid // Fast path for click listeners (which is most often) to avoid
// iterating through props. // iterating through props.
patchProp(el, 'onClick', null, props.onClick) patchProp(el, 'onClick', null, props.onClick)
@ -223,16 +223,13 @@ export function createHydrationFunctions(
} }
// vnode / directive hooks // vnode / directive hooks
let vnodeHooks: VNodeHook | null | undefined let vnodeHooks: VNodeHook | null | undefined
if ((vnodeHooks = props && props.onVnodeBeforeMount) != null) { if ((vnodeHooks = props && props.onVnodeBeforeMount)) {
invokeVNodeHook(vnodeHooks, parentComponent, vnode) invokeVNodeHook(vnodeHooks, parentComponent, vnode)
} }
if (dirs != null) { if (dirs) {
invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount') invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount')
} }
if ( if ((vnodeHooks = props && props.onVnodeMounted) || dirs) {
(vnodeHooks = props && props.onVnodeMounted) != null ||
dirs != null
) {
queueEffectWithSuspense(() => { queueEffectWithSuspense(() => {
vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode) vnodeHooks && invokeVNodeHook(vnodeHooks, parentComponent, vnode)
dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted') dirs && invokeDirectiveHook(vnode, null, parentComponent, 'mounted')
@ -242,7 +239,7 @@ export function createHydrationFunctions(
if ( if (
shapeFlag & ShapeFlags.ARRAY_CHILDREN && shapeFlag & ShapeFlags.ARRAY_CHILDREN &&
// skip if element has innerHTML / textContent // skip if element has innerHTML / textContent
!(props !== null && (props.innerHTML || props.textContent)) !(props && (props.innerHTML || props.textContent))
) { ) {
let next = hydrateChildren( let next = hydrateChildren(
el.firstChild, el.firstChild,
@ -291,7 +288,7 @@ export function createHydrationFunctions(
parentSuspense: SuspenseBoundary | null, parentSuspense: SuspenseBoundary | null,
optimized: boolean optimized: boolean
): Node | null => { ): Node | null => {
optimized = optimized || vnode.dynamicChildren !== null optimized = optimized || !!vnode.dynamicChildren
const children = vnode.children as VNode[] const children = vnode.children as VNode[]
const l = children.length const l = children.length
let hasWarned = false let hasWarned = false
@ -369,7 +366,7 @@ export function createHydrationFunctions(
const target = (vnode.target = isString(targetSelector) const target = (vnode.target = isString(targetSelector)
? document.querySelector(targetSelector) ? document.querySelector(targetSelector)
: targetSelector) : targetSelector)
if (target != null && vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) { if (target && vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
hydrateChildren( hydrateChildren(
target.firstChild, target.firstChild,
vnode, vnode,

View File

@ -348,7 +348,7 @@ function baseCreateRenderer<
optimized = false optimized = false
) => { ) => {
// patching & not same type, unmount old tree // patching & not same type, unmount old tree
if (n1 != null && !isSameVNodeType(n1, n2)) { if (n1 && !isSameVNodeType(n1, n2)) {
anchor = getNextHostNode(n1) anchor = getNextHostNode(n1)
unmount(n1, parentComponent, parentSuspense, true) unmount(n1, parentComponent, parentSuspense, true)
n1 = null n1 = null
@ -476,7 +476,7 @@ function baseCreateRenderer<
anchor: HostNode | null, anchor: HostNode | null,
isSVG: boolean isSVG: boolean
) => { ) => {
if (n2.el != null && hostCloneNode !== undefined) { if (n2.el && hostCloneNode !== undefined) {
hostInsert(hostCloneNode(n2.el), container, anchor) hostInsert(hostCloneNode(n2.el), container, anchor)
} else { } else {
// static nodes are only present when used with compiler-dom/runtime-dom // static nodes are only present when used with compiler-dom/runtime-dom
@ -514,7 +514,7 @@ function baseCreateRenderer<
} else { } else {
patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized) patchElement(n1, n2, parentComponent, parentSuspense, isSVG, optimized)
} }
if (n2.ref !== null && parentComponent !== null) { if (n2.ref != null && parentComponent) {
setRef(n2.ref, n1 && n1.ref, parentComponent, n2.el) setRef(n2.ref, n1 && n1.ref, parentComponent, n2.el)
} }
} }
@ -540,7 +540,7 @@ function baseCreateRenderer<
dirs dirs
} = vnode } = vnode
if ( if (
vnode.el !== null && vnode.el &&
hostCloneNode !== undefined && hostCloneNode !== undefined &&
patchFlag === PatchFlags.HOISTED patchFlag === PatchFlags.HOISTED
) { ) {
@ -551,29 +551,29 @@ function baseCreateRenderer<
} else { } else {
el = vnode.el = hostCreateElement(vnode.type as string, isSVG) el = vnode.el = hostCreateElement(vnode.type as string, isSVG)
// props // props
if (props != null) { if (props) {
for (const key in props) { for (const key in props) {
if (!isReservedProp(key)) { if (!isReservedProp(key)) {
hostPatchProp(el, key, null, props[key], isSVG) hostPatchProp(el, key, null, props[key], isSVG)
} }
} }
if ((vnodeHook = props.onVnodeBeforeMount) != null) { if ((vnodeHook = props.onVnodeBeforeMount)) {
invokeVNodeHook(vnodeHook, parentComponent, vnode) invokeVNodeHook(vnodeHook, parentComponent, vnode)
} }
} }
if (dirs != null) { if (dirs) {
invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount') invokeDirectiveHook(vnode, null, parentComponent, 'beforeMount')
} }
// scopeId // scopeId
if (__BUNDLER__) { if (__BUNDLER__) {
if (scopeId !== null) { if (scopeId) {
hostSetScopeId(el, scopeId) hostSetScopeId(el, scopeId)
} }
const treeOwnerId = parentComponent && parentComponent.type.__scopeId const treeOwnerId = parentComponent && parentComponent.type.__scopeId
// vnode's own scopeId and the current patched component's scopeId is // vnode's own scopeId and the current patched component's scopeId is
// different - this is a slot content node. // different - this is a slot content node.
if (treeOwnerId != null && treeOwnerId !== scopeId) { if (treeOwnerId && treeOwnerId !== scopeId) {
hostSetScopeId(el, treeOwnerId + '-s') hostSetScopeId(el, treeOwnerId + '-s')
} }
} }
@ -589,19 +589,19 @@ function baseCreateRenderer<
parentComponent, parentComponent,
parentSuspense, parentSuspense,
isSVG && type !== 'foreignObject', isSVG && type !== 'foreignObject',
optimized || vnode.dynamicChildren !== null optimized || !!vnode.dynamicChildren
) )
} }
if (transition != null && !transition.persisted) { if (transition && !transition.persisted) {
transition.beforeEnter(el) transition.beforeEnter(el)
} }
} }
hostInsert(el, container, anchor) hostInsert(el, container, anchor)
if ( if (
(vnodeHook = props && props.onVnodeMounted) != null || (vnodeHook = props && props.onVnodeMounted) ||
(transition != null && !transition.persisted) || (transition && !transition.persisted) ||
dirs != null dirs
) { ) {
queuePostRenderEffect(() => { queuePostRenderEffect(() => {
vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode) vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode)
@ -652,10 +652,10 @@ function baseCreateRenderer<
const newProps = n2.props || EMPTY_OBJ const newProps = n2.props || EMPTY_OBJ
let vnodeHook: VNodeHook | undefined | null let vnodeHook: VNodeHook | undefined | null
if ((vnodeHook = newProps.onVnodeBeforeUpdate) != null) { if ((vnodeHook = newProps.onVnodeBeforeUpdate)) {
invokeVNodeHook(vnodeHook, parentComponent, n2, n1) invokeVNodeHook(vnodeHook, parentComponent, n2, n1)
} }
if (dirs != null) { if (dirs) {
invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate') invokeDirectiveHook(n2, n1, parentComponent, 'beforeUpdate')
} }
@ -748,7 +748,7 @@ function baseCreateRenderer<
} }
const areChildrenSVG = isSVG && n2.type !== 'foreignObject' const areChildrenSVG = isSVG && n2.type !== 'foreignObject'
if (dynamicChildren != null) { if (dynamicChildren) {
patchBlockChildren( patchBlockChildren(
n1.dynamicChildren!, n1.dynamicChildren!,
dynamicChildren, dynamicChildren,
@ -770,7 +770,7 @@ function baseCreateRenderer<
) )
} }
if ((vnodeHook = newProps.onVnodeUpdated) != null || dirs != null) { if ((vnodeHook = newProps.onVnodeUpdated) || dirs) {
queuePostRenderEffect(() => { queuePostRenderEffect(() => {
vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1) vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, n2, n1)
dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated') dirs && invokeDirectiveHook(n2, n1, parentComponent, 'updated')
@ -906,7 +906,7 @@ function baseCreateRenderer<
optimized optimized
) )
} else { } else {
if (patchFlag & PatchFlags.STABLE_FRAGMENT && dynamicChildren != null) { if (patchFlag & PatchFlags.STABLE_FRAGMENT && dynamicChildren) {
// a stable fragment (template root or <template v-for>) doesn't need to // a stable fragment (template root or <template v-for>) doesn't need to
// patch children order, but it may contain dynamicChildren. // patch children order, but it may contain dynamicChildren.
patchBlockChildren( patchBlockChildren(
@ -997,7 +997,7 @@ function baseCreateRenderer<
n2.el = n1.el n2.el = n1.el
} }
} }
if (n2.ref !== null && parentComponent !== null) { if (n2.ref != null && parentComponent) {
if (__DEV__ && !(n2.shapeFlag & ShapeFlags.STATEFUL_COMPONENT)) { if (__DEV__ && !(n2.shapeFlag & ShapeFlags.STATEFUL_COMPONENT)) {
pushWarningContext(n2) pushWarningContext(n2)
warn( warn(
@ -1023,7 +1023,7 @@ function baseCreateRenderer<
parentComponent parentComponent
)) ))
if (__HMR__ && instance.type.__hmrId != null) { if (__HMR__ && instance.type.__hmrId) {
registerHMR(instance) registerHMR(instance)
} }
@ -1089,11 +1089,11 @@ function baseCreateRenderer<
const { bm, m, a, parent } = instance const { bm, m, a, parent } = instance
const subTree = (instance.subTree = renderComponentRoot(instance)) const subTree = (instance.subTree = renderComponentRoot(instance))
// beforeMount hook // beforeMount hook
if (bm !== null) { if (bm) {
invokeHooks(bm) invokeHooks(bm)
} }
// onVnodeBeforeMount // onVnodeBeforeMount
if ((vnodeHook = props && props.onVnodeBeforeMount) != null) { if ((vnodeHook = props && props.onVnodeBeforeMount)) {
invokeVNodeHook(vnodeHook, parent, initialVNode) invokeVNodeHook(vnodeHook, parent, initialVNode)
} }
if (el && hydrateNode) { if (el && hydrateNode) {
@ -1117,18 +1117,18 @@ function baseCreateRenderer<
initialVNode.el = subTree.el initialVNode.el = subTree.el
} }
// mounted hook // mounted hook
if (m !== null) { if (m) {
queuePostRenderEffect(m, parentSuspense) queuePostRenderEffect(m, parentSuspense)
} }
// onVnodeMounted // onVnodeMounted
if ((vnodeHook = props && props.onVnodeMounted) != null) { if ((vnodeHook = props && props.onVnodeMounted)) {
queuePostRenderEffect(() => { queuePostRenderEffect(() => {
invokeVNodeHook(vnodeHook!, parent, initialVNode) invokeVNodeHook(vnodeHook!, parent, initialVNode)
}, parentSuspense) }, parentSuspense)
} }
// activated hook for keep-alive roots. // activated hook for keep-alive roots.
if ( if (
a !== null && a &&
initialVNode.shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE initialVNode.shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE
) { ) {
queuePostRenderEffect(a, parentSuspense) queuePostRenderEffect(a, parentSuspense)
@ -1144,7 +1144,7 @@ function baseCreateRenderer<
pushWarningContext(next || instance.vnode) pushWarningContext(next || instance.vnode)
} }
if (next !== null) { if (next) {
updateComponentPreRender(instance, next) updateComponentPreRender(instance, next)
} else { } else {
next = vnode next = vnode
@ -1154,13 +1154,11 @@ function baseCreateRenderer<
instance.subTree = nextTree instance.subTree = nextTree
next.el = vnode.el next.el = vnode.el
// beforeUpdate hook // beforeUpdate hook
if (bu !== null) { if (bu) {
invokeHooks(bu) invokeHooks(bu)
} }
// onVnodeBeforeUpdate // onVnodeBeforeUpdate
if ( if ((vnodeHook = next.props && next.props.onVnodeBeforeUpdate)) {
(vnodeHook = next.props && next.props.onVnodeBeforeUpdate) != null
) {
invokeVNodeHook(vnodeHook, parent, next, vnode) invokeVNodeHook(vnodeHook, parent, next, vnode)
} }
// reset refs // reset refs
@ -1187,11 +1185,11 @@ function baseCreateRenderer<
updateHOCHostEl(instance, nextTree.el) updateHOCHostEl(instance, nextTree.el)
} }
// updated hook // updated hook
if (u !== null) { if (u) {
queuePostRenderEffect(u, parentSuspense) queuePostRenderEffect(u, parentSuspense)
} }
// onVnodeUpdated // onVnodeUpdated
if ((vnodeHook = next.props && next.props.onVnodeUpdated) != null) { if ((vnodeHook = next.props && next.props.onVnodeUpdated)) {
queuePostRenderEffect(() => { queuePostRenderEffect(() => {
invokeVNodeHook(vnodeHook!, parent, next!, vnode) invokeVNodeHook(vnodeHook!, parent, next!, vnode)
}, parentSuspense) }, parentSuspense)
@ -1632,7 +1630,7 @@ function baseCreateRenderer<
const needTransition = const needTransition =
type !== MoveType.REORDER && type !== MoveType.REORDER &&
shapeFlag & ShapeFlags.ELEMENT && shapeFlag & ShapeFlags.ELEMENT &&
transition != null transition
if (needTransition) { if (needTransition) {
if (type === MoveType.ENTER) { if (type === MoveType.ENTER) {
transition!.beforeEnter(el!) transition!.beforeEnter(el!)
@ -1666,15 +1664,15 @@ function baseCreateRenderer<
doRemove = false doRemove = false
) => { ) => {
const { props, ref, children, dynamicChildren, shapeFlag, dirs } = vnode const { props, ref, children, dynamicChildren, shapeFlag, dirs } = vnode
const shouldInvokeDirs = dirs != null && shapeFlag & ShapeFlags.ELEMENT const shouldInvokeDirs = shapeFlag & ShapeFlags.ELEMENT && dirs
let vnodeHook: VNodeHook | undefined | null let vnodeHook: VNodeHook | undefined | null
// unset ref // unset ref
if (ref !== null && parentComponent !== null) { if (ref != null && parentComponent) {
setRef(ref, null, parentComponent, null) setRef(ref, null, parentComponent, null)
} }
if ((vnodeHook = props && props.onVnodeBeforeUnmount) != null) { if ((vnodeHook = props && props.onVnodeBeforeUnmount)) {
invokeVNodeHook(vnodeHook, parentComponent, vnode) invokeVNodeHook(vnodeHook, parentComponent, vnode)
} }
@ -1694,7 +1692,7 @@ function baseCreateRenderer<
invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount') invokeDirectiveHook(vnode, null, parentComponent, 'beforeUnmount')
} }
if (dynamicChildren != null) { if (dynamicChildren) {
// fast path for block nodes: only need to unmount dynamic children. // fast path for block nodes: only need to unmount dynamic children.
unmountChildren(dynamicChildren, parentComponent, parentSuspense) unmountChildren(dynamicChildren, parentComponent, parentSuspense)
} else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) { } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
@ -1710,10 +1708,7 @@ function baseCreateRenderer<
} }
} }
if ( if ((vnodeHook = props && props.onVnodeUnmounted) || shouldInvokeDirs) {
(vnodeHook = props && props.onVnodeUnmounted) != null ||
shouldInvokeDirs
) {
queuePostRenderEffect(() => { queuePostRenderEffect(() => {
vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode) vnodeHook && invokeVNodeHook(vnodeHook, parentComponent, vnode)
shouldInvokeDirs && shouldInvokeDirs &&
@ -1731,18 +1726,14 @@ function baseCreateRenderer<
const performRemove = () => { const performRemove = () => {
hostRemove(el!) hostRemove(el!)
if ( if (transition && !transition.persisted && transition.afterLeave) {
transition != null &&
!transition.persisted &&
transition.afterLeave
) {
transition.afterLeave() transition.afterLeave()
} }
} }
if ( if (
vnode.shapeFlag & ShapeFlags.ELEMENT && vnode.shapeFlag & ShapeFlags.ELEMENT &&
transition != null && transition &&
!transition.persisted !transition.persisted
) { ) {
const { leave, delayLeave } = transition const { leave, delayLeave } = transition
@ -1774,33 +1765,33 @@ function baseCreateRenderer<
parentSuspense: HostSuspenseBoundary | null, parentSuspense: HostSuspenseBoundary | null,
doRemove?: boolean doRemove?: boolean
) => { ) => {
if (__HMR__ && instance.type.__hmrId != null) { if (__HMR__ && instance.type.__hmrId) {
unregisterHMR(instance) unregisterHMR(instance)
} }
const { bum, effects, update, subTree, um, da, isDeactivated } = instance const { bum, effects, update, subTree, um, da, isDeactivated } = instance
// beforeUnmount hook // beforeUnmount hook
if (bum !== null) { if (bum) {
invokeHooks(bum) invokeHooks(bum)
} }
if (effects !== null) { if (effects) {
for (let i = 0; i < effects.length; i++) { for (let i = 0; i < effects.length; i++) {
stop(effects[i]) stop(effects[i])
} }
} }
// update may be null if a component is unmounted before its async // update may be null if a component is unmounted before its async
// setup has resolved. // setup has resolved.
if (update !== null) { if (update) {
stop(update) stop(update)
unmount(subTree, instance, parentSuspense, doRemove) unmount(subTree, instance, parentSuspense, doRemove)
} }
// unmounted hook // unmounted hook
if (um !== null) { if (um) {
queuePostRenderEffect(um, parentSuspense) queuePostRenderEffect(um, parentSuspense)
} }
// deactivated hook // deactivated hook
if ( if (
da !== null && da &&
!isDeactivated && !isDeactivated &&
instance.vnode.shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE instance.vnode.shapeFlag & ShapeFlags.COMPONENT_SHOULD_KEEP_ALIVE
) { ) {
@ -1815,10 +1806,10 @@ function baseCreateRenderer<
// cause the suspense to resolve immediately if that was the last dep. // cause the suspense to resolve immediately if that was the last dep.
if ( if (
__FEATURE_SUSPENSE__ && __FEATURE_SUSPENSE__ &&
parentSuspense !== null && parentSuspense &&
!parentSuspense.isResolved && !parentSuspense.isResolved &&
!parentSuspense.isUnmounted && !parentSuspense.isUnmounted &&
instance.asyncDep !== null && instance.asyncDep &&
!instance.asyncResolved !instance.asyncResolved
) { ) {
parentSuspense.deps-- parentSuspense.deps--
@ -1869,7 +1860,7 @@ function baseCreateRenderer<
const renderContext = toRaw(owner.renderContext) const renderContext = toRaw(owner.renderContext)
// unset old ref // unset old ref
if (oldRef !== null && oldRef !== ref) { if (oldRef != null && oldRef !== ref) {
if (isString(oldRef)) { if (isString(oldRef)) {
refs[oldRef] = null refs[oldRef] = null
const oldSetupRef = renderContext[oldRef] const oldSetupRef = renderContext[oldRef]

View File

@ -196,7 +196,7 @@ export function createBlock(
currentBlock = blockStack[blockStack.length - 1] || null currentBlock = blockStack[blockStack.length - 1] || null
// a block is always going to be patched, so track it as a child of its // a block is always going to be patched, so track it as a child of its
// parent block // parent block
if (currentBlock !== null) { if (currentBlock) {
currentBlock.push(vnode) currentBlock.push(vnode)
} }
return vnode return vnode
@ -239,13 +239,13 @@ export function createVNode(
} }
// class & style normalization. // class & style normalization.
if (props !== null) { if (props) {
// for reactive or proxy objects, we need to clone it to enable mutation. // for reactive or proxy objects, we need to clone it to enable mutation.
if (isReactive(props) || SetupProxySymbol in props) { if (isReactive(props) || SetupProxySymbol in props) {
props = extend({}, props) props = extend({}, props)
} }
let { class: klass, style } = props let { class: klass, style } = props
if (klass != null && !isString(klass)) { if (klass && !isString(klass)) {
props.class = normalizeClass(klass) props.class = normalizeClass(klass)
} }
if (isObject(style)) { if (isObject(style)) {
@ -275,9 +275,9 @@ export function createVNode(
_isVNode: true, _isVNode: true,
type, type,
props, props,
key: props !== null && props.key !== undefined ? props.key : null, key: props && props.key !== undefined ? props.key : null,
ref: ref:
props !== null && props.ref !== undefined props && props.ref !== undefined
? [currentRenderingInstance!, props.ref] ? [currentRenderingInstance!, props.ref]
: null, : null,
scopeId: currentScopeId, scopeId: currentScopeId,
@ -304,7 +304,7 @@ export function createVNode(
// the next vnode so that it can be properly unmounted later. // the next vnode so that it can be properly unmounted later.
if ( if (
shouldTrack > 0 && shouldTrack > 0 &&
currentBlock !== null && currentBlock &&
// the EVENTS flag is only for hydration and if it is the only flag, the // the EVENTS flag is only for hydration and if it is the only flag, the
// vnode should not be considered dynamic due to handler caching. // vnode should not be considered dynamic due to handler caching.
patchFlag !== PatchFlags.HYDRATE_EVENTS && patchFlag !== PatchFlags.HYDRATE_EVENTS &&

View File

@ -14,7 +14,7 @@ export function patchDOMProp(
parentSuspense: any, parentSuspense: any,
unmountChildren: any unmountChildren: any
) { ) {
if ((key === 'innerHTML' || key === 'textContent') && prevChildren != null) { if ((key === 'innerHTML' || key === 'textContent') && prevChildren) {
unmountChildren(prevChildren, parentComponent, parentSuspense) unmountChildren(prevChildren, parentComponent, parentSuspense)
el[key] = value == null ? '' : value el[key] = value == null ? '' : value
return return

View File

@ -8,7 +8,7 @@ let tempSVGContainer: SVGElement
export const nodeOps: Omit<RendererOptions<Node, Element>, 'patchProp'> = { export const nodeOps: Omit<RendererOptions<Node, Element>, 'patchProp'> = {
insert: (child, parent, anchor) => { insert: (child, parent, anchor) => {
if (anchor != null) { if (anchor) {
parent.insertBefore(child, anchor) parent.insertBefore(child, anchor)
} else { } else {
parent.appendChild(child) parent.appendChild(child)
@ -17,7 +17,7 @@ export const nodeOps: Omit<RendererOptions<Node, Element>, 'patchProp'> = {
remove: child => { remove: child => {
const parent = child.parentNode const parent = child.parentNode
if (parent != null) { if (parent) {
parent.removeChild(child) parent.removeChild(child)
} }
}, },

View File

@ -139,7 +139,7 @@ function setText(node: TestText, text: string) {
function insert(child: TestNode, parent: TestElement, ref?: TestNode | null) { function insert(child: TestNode, parent: TestElement, ref?: TestNode | null) {
let refIndex let refIndex
if (ref != null) { if (ref) {
refIndex = parent.children.indexOf(ref) refIndex = parent.children.indexOf(ref)
if (refIndex === -1) { if (refIndex === -1) {
console.error('ref: ', ref) console.error('ref: ', ref)
@ -168,7 +168,7 @@ function insert(child: TestNode, parent: TestElement, ref?: TestNode | null) {
function remove(child: TestNode, logOp: boolean = true) { function remove(child: TestNode, logOp: boolean = true) {
const parent = child.parentNode const parent = child.parentNode
if (parent != null) { if (parent) {
if (logOp) { if (logOp) {
logNodeOp({ logNodeOp({
type: NodeOpTypes.REMOVE, type: NodeOpTypes.REMOVE,

View File

@ -295,20 +295,20 @@ function renderElementVNode(
let { props, children, shapeFlag, scopeId, dirs } = vnode let { props, children, shapeFlag, scopeId, dirs } = vnode
let openTag = `<${tag}` let openTag = `<${tag}`
if (dirs !== null) { if (dirs) {
props = applySSRDirectives(vnode, props, dirs) props = applySSRDirectives(vnode, props, dirs)
} }
if (props !== null) { if (props) {
openTag += ssrRenderAttrs(props, tag) openTag += ssrRenderAttrs(props, tag)
} }
if (scopeId !== null) { if (scopeId) {
openTag += ` ${scopeId}` openTag += ` ${scopeId}`
const treeOwnerId = parentComponent && parentComponent.type.__scopeId const treeOwnerId = parentComponent && parentComponent.type.__scopeId
// vnode's own scopeId and the current rendering component's scopeId is // vnode's own scopeId and the current rendering component's scopeId is
// different - this is a slot content node. // different - this is a slot content node.
if (treeOwnerId != null && treeOwnerId !== scopeId) { if (treeOwnerId && treeOwnerId !== scopeId) {
openTag += ` ${treeOwnerId}-s` openTag += ` ${treeOwnerId}-s`
} }
} }
@ -316,7 +316,7 @@ function renderElementVNode(
push(openTag + `>`) push(openTag + `>`)
if (!isVoidTag(tag)) { if (!isVoidTag(tag)) {
let hasChildrenOverride = false let hasChildrenOverride = false
if (props !== null) { if (props) {
if (props.innerHTML) { if (props.innerHTML) {
hasChildrenOverride = true hasChildrenOverride = true
push(props.innerHTML) push(props.innerHTML)