feat: detailed info in renderTriggered + hint for skipping slot updates
This commit is contained in:
		
							parent
							
								
									6027d480f3
								
							
						
					
					
						commit
						64029b4a54
					
				@ -204,9 +204,7 @@ export function shouldUpdateComponent(
 | 
				
			|||||||
  const { data: prevProps, childFlags: prevChildFlags } = prevVNode
 | 
					  const { data: prevProps, childFlags: prevChildFlags } = prevVNode
 | 
				
			||||||
  const { data: nextProps, childFlags: nextChildFlags } = nextVNode
 | 
					  const { data: nextProps, childFlags: nextChildFlags } = nextVNode
 | 
				
			||||||
  // If has different slots content, or has non-compiled slots,
 | 
					  // If has different slots content, or has non-compiled slots,
 | 
				
			||||||
  // the child needs to be force updated. It's ok to call $forceUpdate
 | 
					  // the child needs to be force updated.
 | 
				
			||||||
  // again even if props update has already queued an update, as the
 | 
					 | 
				
			||||||
  // scheduler will not queue the same update twice.
 | 
					 | 
				
			||||||
  if (
 | 
					  if (
 | 
				
			||||||
    prevChildFlags !== nextChildFlags ||
 | 
					    prevChildFlags !== nextChildFlags ||
 | 
				
			||||||
    (nextChildFlags & ChildrenFlags.DYNAMIC_SLOTS) > 0
 | 
					    (nextChildFlags & ChildrenFlags.DYNAMIC_SLOTS) > 0
 | 
				
			||||||
@ -235,11 +233,49 @@ export function shouldUpdateComponent(
 | 
				
			|||||||
  return false
 | 
					  return false
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// DEV only
 | 
				
			||||||
export function getReasonForComponentUpdate(
 | 
					export function getReasonForComponentUpdate(
 | 
				
			||||||
  prevVNode: VNode,
 | 
					  prevVNode: VNode,
 | 
				
			||||||
  nextVNode: VNode
 | 
					  nextVNode: VNode
 | 
				
			||||||
): any {
 | 
					): any {
 | 
				
			||||||
  // TODO: extract more detailed information on why the component is updating
 | 
					  const reasons = []
 | 
				
			||||||
 | 
					  const { childFlags: prevChildFlags } = prevVNode
 | 
				
			||||||
 | 
					  const { childFlags: nextChildFlags } = nextVNode
 | 
				
			||||||
 | 
					  if (
 | 
				
			||||||
 | 
					    prevChildFlags !== nextChildFlags ||
 | 
				
			||||||
 | 
					    (nextChildFlags & ChildrenFlags.DYNAMIC_SLOTS) > 0
 | 
				
			||||||
 | 
					  ) {
 | 
				
			||||||
 | 
					    reasons.push({
 | 
				
			||||||
 | 
					      type: `slots may have changed`,
 | 
				
			||||||
 | 
					      tip: `use function slots + $stable: true to avoid slot-triggered child updates.`
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const prevProps = prevVNode.data || EMPTY_OBJ
 | 
				
			||||||
 | 
					  const nextProps = nextVNode.data || EMPTY_OBJ
 | 
				
			||||||
 | 
					  for (const key in nextProps) {
 | 
				
			||||||
 | 
					    if (nextProps[key] !== prevProps[key]) {
 | 
				
			||||||
 | 
					      reasons.push({
 | 
				
			||||||
 | 
					        type: 'prop changed',
 | 
				
			||||||
 | 
					        key,
 | 
				
			||||||
 | 
					        value: nextProps[key],
 | 
				
			||||||
 | 
					        oldValue: prevProps[key]
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  for (const key in prevProps) {
 | 
				
			||||||
 | 
					    if (!(key in nextProps)) {
 | 
				
			||||||
 | 
					      reasons.push({
 | 
				
			||||||
 | 
					        type: 'prop changed',
 | 
				
			||||||
 | 
					        key,
 | 
				
			||||||
 | 
					        value: undefined,
 | 
				
			||||||
 | 
					        oldValue: prevProps[key]
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    type: 'triggered by parent',
 | 
				
			||||||
 | 
					    reasons
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function createComponentClassFromOptions(
 | 
					export function createComponentClassFromOptions(
 | 
				
			||||||
 | 
				
			|||||||
@ -22,7 +22,8 @@ export const Portal = Symbol()
 | 
				
			|||||||
type RawChildType = VNode | string | number | boolean | null | undefined
 | 
					type RawChildType = VNode | string | number | boolean | null | undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type RawSlots = {
 | 
					export type RawSlots = {
 | 
				
			||||||
  [name: string]: () => RawChildrenType
 | 
					  $stable?: boolean
 | 
				
			||||||
 | 
					  [name: string]: RawChildType | (() => RawChildrenType)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type RawChildrenType = RawChildType | RawChildType[]
 | 
					export type RawChildrenType = RawChildType | RawChildType[]
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,7 @@ import { RawChildrenType, RawSlots } from './h'
 | 
				
			|||||||
import { FunctionalHandle } from './createRenderer'
 | 
					import { FunctionalHandle } from './createRenderer'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const handlersRE = /^on|^vnode/
 | 
					const handlersRE = /^on|^vnode/
 | 
				
			||||||
 | 
					const STABLE_SLOTS_HINT = '$stable'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Vue core is platform agnostic, so we are not using Element for "DOM" nodes.
 | 
					// Vue core is platform agnostic, so we are not using Element for "DOM" nodes.
 | 
				
			||||||
export interface RenderNode {
 | 
					export interface RenderNode {
 | 
				
			||||||
@ -226,6 +227,10 @@ export function createComponentVNode(
 | 
				
			|||||||
      } else if (isObject(children) && !(children as any)._isVNode) {
 | 
					      } else if (isObject(children) && !(children as any)._isVNode) {
 | 
				
			||||||
        // slot object as children
 | 
					        // slot object as children
 | 
				
			||||||
        slots = children
 | 
					        slots = children
 | 
				
			||||||
 | 
					        // special manual optimization hint for raw render fn users
 | 
				
			||||||
 | 
					        if (slots[STABLE_SLOTS_HINT]) {
 | 
				
			||||||
 | 
					          childFlags = ChildrenFlags.STABLE_SLOTS
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        slots = { default: () => children }
 | 
					        slots = { default: () => children }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
@ -418,6 +423,9 @@ function normalizeSlots(slots: { [name: string]: any }): Slots {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  const normalized = { _normalized: true } as any
 | 
					  const normalized = { _normalized: true } as any
 | 
				
			||||||
  for (const name in slots) {
 | 
					  for (const name in slots) {
 | 
				
			||||||
 | 
					    if (name === STABLE_SLOTS_HINT) {
 | 
				
			||||||
 | 
					      continue
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    normalized[name] = (...args: any[]) => normalizeSlot(slots[name](...args))
 | 
					    normalized[name] = (...args: any[]) => normalizeSlot(slots[name](...args))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return normalized
 | 
					  return normalized
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user