refactor: use const enums for flags
This commit is contained in:
		
							parent
							
								
									f26cd5dfe4
								
							
						
					
					
						commit
						f3e9848bb2
					
				@ -0,0 +1 @@
 | 
			
		||||
// TODO
 | 
			
		||||
@ -0,0 +1 @@
 | 
			
		||||
// TODO
 | 
			
		||||
@ -3,9 +3,9 @@ import { ReactiveEffect, UnwrapRef, reactive, immutable } from '@vue/reactivity'
 | 
			
		||||
import { EMPTY_OBJ, isFunction, capitalize, invokeHandlers } from '@vue/shared'
 | 
			
		||||
import { RenderProxyHandlers } from './componentProxy'
 | 
			
		||||
import { ComponentPropsOptions, ExtractPropTypes } from './componentProps'
 | 
			
		||||
import { PROPS, DYNAMIC_SLOTS, FULL_PROPS } from './patchFlags'
 | 
			
		||||
import { Slots } from './componentSlots'
 | 
			
		||||
import { STATEFUL_COMPONENT } from './typeFlags'
 | 
			
		||||
import { PatchFlags } from './patchFlags'
 | 
			
		||||
import { ShapeFlags } from './shapeFlags'
 | 
			
		||||
 | 
			
		||||
export type Data = { [key: string]: unknown }
 | 
			
		||||
 | 
			
		||||
@ -302,7 +302,7 @@ export function renderComponentRoot(instance: ComponentInstance): VNode {
 | 
			
		||||
    parent,
 | 
			
		||||
    root
 | 
			
		||||
  } = instance
 | 
			
		||||
  if (vnode.shapeFlag & STATEFUL_COMPONENT) {
 | 
			
		||||
  if (vnode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT) {
 | 
			
		||||
    return normalizeVNode(
 | 
			
		||||
      (instance.render as RenderFunction).call(renderProxy, props, setupContext)
 | 
			
		||||
    )
 | 
			
		||||
@ -332,15 +332,15 @@ export function shouldUpdateComponent(
 | 
			
		||||
  const { props: prevProps, children: prevChildren } = prevVNode
 | 
			
		||||
  const { props: nextProps, children: nextChildren, patchFlag } = nextVNode
 | 
			
		||||
  if (patchFlag) {
 | 
			
		||||
    if (patchFlag & DYNAMIC_SLOTS) {
 | 
			
		||||
    if (patchFlag & PatchFlags.DYNAMIC_SLOTS) {
 | 
			
		||||
      // slot content that references values that might have changed,
 | 
			
		||||
      // e.g. in a v-for
 | 
			
		||||
      return true
 | 
			
		||||
    }
 | 
			
		||||
    if (patchFlag & FULL_PROPS) {
 | 
			
		||||
    if (patchFlag & PatchFlags.FULL_PROPS) {
 | 
			
		||||
      // presence of this flag indicates props are always non-null
 | 
			
		||||
      return hasPropsChanged(prevProps as Data, nextProps as Data)
 | 
			
		||||
    } else if (patchFlag & PROPS) {
 | 
			
		||||
    } else if (patchFlag & PatchFlags.PROPS) {
 | 
			
		||||
      const dynamicProps = nextVNode.dynamicProps as string[]
 | 
			
		||||
      for (let i = 0; i < dynamicProps.length; i++) {
 | 
			
		||||
        const key = dynamicProps[i]
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@ import {
 | 
			
		||||
} from '@vue/shared'
 | 
			
		||||
import { warn } from './warning'
 | 
			
		||||
import { Data, ComponentInstance } from './component'
 | 
			
		||||
import { FULL_PROPS } from './patchFlags'
 | 
			
		||||
import { PatchFlags } from './patchFlags'
 | 
			
		||||
 | 
			
		||||
export type ComponentPropsOptions<P = Data> = {
 | 
			
		||||
  [K in keyof P]: Prop<P[K]> | null
 | 
			
		||||
@ -167,7 +167,10 @@ export function resolveProps(
 | 
			
		||||
  // in case of dynamic props, check if we need to delete keys from
 | 
			
		||||
  // the props proxy
 | 
			
		||||
  const { patchFlag } = instance.vnode
 | 
			
		||||
  if (propsProxy !== null && (patchFlag === 0 || patchFlag & FULL_PROPS)) {
 | 
			
		||||
  if (
 | 
			
		||||
    propsProxy !== null &&
 | 
			
		||||
    (patchFlag === 0 || patchFlag & PatchFlags.FULL_PROPS)
 | 
			
		||||
  ) {
 | 
			
		||||
    const rawInitialProps = toRaw(propsProxy)
 | 
			
		||||
    for (const key in rawInitialProps) {
 | 
			
		||||
      if (!props.hasOwnProperty(key)) {
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
import { ComponentInstance } from './component'
 | 
			
		||||
import { VNode, NormalizedChildren, normalizeVNode, VNodeChild } from './vnode'
 | 
			
		||||
import { isArray, isFunction } from '@vue/shared'
 | 
			
		||||
import { SLOTS_CHILDREN } from './typeFlags'
 | 
			
		||||
import { ShapeFlags } from './shapeFlags'
 | 
			
		||||
 | 
			
		||||
export type Slot = (...args: any[]) => VNode[]
 | 
			
		||||
export type Slots = Readonly<{
 | 
			
		||||
@ -24,7 +24,7 @@ export function resolveSlots(
 | 
			
		||||
  children: NormalizedChildren
 | 
			
		||||
) {
 | 
			
		||||
  let slots: Slots | void
 | 
			
		||||
  if (instance.vnode.shapeFlag & SLOTS_CHILDREN) {
 | 
			
		||||
  if (instance.vnode.shapeFlag & ShapeFlags.SLOTS_CHILDREN) {
 | 
			
		||||
    if ((children as any)._normalized) {
 | 
			
		||||
      // pre-normalized slots object generated by compiler
 | 
			
		||||
      slots = children as Slots
 | 
			
		||||
 | 
			
		||||
@ -21,15 +21,6 @@ import {
 | 
			
		||||
  isReservedProp,
 | 
			
		||||
  isFunction
 | 
			
		||||
} from '@vue/shared'
 | 
			
		||||
import {
 | 
			
		||||
  TEXT,
 | 
			
		||||
  CLASS,
 | 
			
		||||
  STYLE,
 | 
			
		||||
  PROPS,
 | 
			
		||||
  KEYED,
 | 
			
		||||
  UNKEYED,
 | 
			
		||||
  FULL_PROPS
 | 
			
		||||
} from './patchFlags'
 | 
			
		||||
import { queueJob, queuePostFlushCb, flushPostFlushCbs } from './scheduler'
 | 
			
		||||
import {
 | 
			
		||||
  effect,
 | 
			
		||||
@ -41,13 +32,8 @@ import {
 | 
			
		||||
} from '@vue/reactivity'
 | 
			
		||||
import { resolveProps } from './componentProps'
 | 
			
		||||
import { resolveSlots } from './componentSlots'
 | 
			
		||||
import {
 | 
			
		||||
  ELEMENT,
 | 
			
		||||
  STATEFUL_COMPONENT,
 | 
			
		||||
  FUNCTIONAL_COMPONENT,
 | 
			
		||||
  TEXT_CHILDREN,
 | 
			
		||||
  ARRAY_CHILDREN
 | 
			
		||||
} from './typeFlags'
 | 
			
		||||
import { PatchFlags } from './patchFlags'
 | 
			
		||||
import { ShapeFlags } from './shapeFlags'
 | 
			
		||||
 | 
			
		||||
const prodEffectOptions = {
 | 
			
		||||
  scheduler: queueJob
 | 
			
		||||
@ -167,7 +153,7 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
        )
 | 
			
		||||
        break
 | 
			
		||||
      default:
 | 
			
		||||
        if (shapeFlag & ELEMENT) {
 | 
			
		||||
        if (shapeFlag & ShapeFlags.ELEMENT) {
 | 
			
		||||
          processElement(
 | 
			
		||||
            n1,
 | 
			
		||||
            n2,
 | 
			
		||||
@ -180,8 +166,8 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
        } else {
 | 
			
		||||
          if (
 | 
			
		||||
            __DEV__ &&
 | 
			
		||||
            !(shapeFlag & STATEFUL_COMPONENT) &&
 | 
			
		||||
            !(shapeFlag & FUNCTIONAL_COMPONENT)
 | 
			
		||||
            !(shapeFlag & ShapeFlags.STATEFUL_COMPONENT) &&
 | 
			
		||||
            !(shapeFlag & ShapeFlags.FUNCTIONAL_COMPONENT)
 | 
			
		||||
          ) {
 | 
			
		||||
            // TODO warn invalid node type
 | 
			
		||||
            debugger
 | 
			
		||||
@ -269,9 +255,9 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
        hostPatchProp(el, key, props[key], null, isSVG)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (shapeFlag & TEXT_CHILDREN) {
 | 
			
		||||
    if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
 | 
			
		||||
      hostSetElementText(el, vnode.children as string)
 | 
			
		||||
    } else if (shapeFlag & ARRAY_CHILDREN) {
 | 
			
		||||
    } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
 | 
			
		||||
      mountChildren(
 | 
			
		||||
        vnode.children as VNodeChildren,
 | 
			
		||||
        el,
 | 
			
		||||
@ -315,13 +301,13 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
      // in this path old node and new node are guaranteed to have the same shape
 | 
			
		||||
      // (i.e. at the exact same position in the source template)
 | 
			
		||||
 | 
			
		||||
      if (patchFlag & FULL_PROPS) {
 | 
			
		||||
      if (patchFlag & PatchFlags.FULL_PROPS) {
 | 
			
		||||
        // element props contain dynamic keys, full diff needed
 | 
			
		||||
        patchProps(el, n2, oldProps, newProps, parentComponent, isSVG)
 | 
			
		||||
      } else {
 | 
			
		||||
        // class
 | 
			
		||||
        // this flag is matched when the element has dynamic class bindings.
 | 
			
		||||
        if (patchFlag & CLASS) {
 | 
			
		||||
        if (patchFlag & PatchFlags.CLASS) {
 | 
			
		||||
          if (oldProps.class !== newProps.class) {
 | 
			
		||||
            hostPatchProp(el, 'class', newProps.class, null, isSVG)
 | 
			
		||||
          }
 | 
			
		||||
@ -329,7 +315,7 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
 | 
			
		||||
        // style
 | 
			
		||||
        // this flag is matched when the element has dynamic style bindings
 | 
			
		||||
        if (patchFlag & STYLE) {
 | 
			
		||||
        if (patchFlag & PatchFlags.STYLE) {
 | 
			
		||||
          hostPatchProp(el, 'style', newProps.style, oldProps.style, isSVG)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -339,7 +325,7 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
        // faster iteration.
 | 
			
		||||
        // Note dynamic keys like :[foo]="bar" will cause this optimization to
 | 
			
		||||
        // bail out and go through a full diff because we need to unset the old key
 | 
			
		||||
        if (patchFlag & PROPS) {
 | 
			
		||||
        if (patchFlag & PatchFlags.PROPS) {
 | 
			
		||||
          // if the flag is present then dynamicProps must be non-null
 | 
			
		||||
          const propsToUpdate = n2.dynamicProps as string[]
 | 
			
		||||
          for (let i = 0; i < propsToUpdate.length; i++) {
 | 
			
		||||
@ -365,7 +351,7 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
      // text
 | 
			
		||||
      // This flag is matched when the element has only dynamic text children.
 | 
			
		||||
      // this flag is terminal (i.e. skips children diffing).
 | 
			
		||||
      if (patchFlag & TEXT) {
 | 
			
		||||
      if (patchFlag & PatchFlags.TEXT) {
 | 
			
		||||
        if (n1.children !== n2.children) {
 | 
			
		||||
          hostSetElementText(el, n2.children as string)
 | 
			
		||||
        }
 | 
			
		||||
@ -495,9 +481,9 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
        ? hostQuerySelector(targetSelector)
 | 
			
		||||
        : null)
 | 
			
		||||
      if (target != null) {
 | 
			
		||||
        if (shapeFlag & TEXT_CHILDREN) {
 | 
			
		||||
        if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
 | 
			
		||||
          hostSetElementText(target, children as string)
 | 
			
		||||
        } else if (shapeFlag & ARRAY_CHILDREN) {
 | 
			
		||||
        } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
 | 
			
		||||
          mountChildren(
 | 
			
		||||
            children as VNodeChildren,
 | 
			
		||||
            target,
 | 
			
		||||
@ -512,7 +498,7 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
    } else {
 | 
			
		||||
      // update content
 | 
			
		||||
      const target = (n2.target = n1.target)
 | 
			
		||||
      if (patchFlag === TEXT) {
 | 
			
		||||
      if (patchFlag === PatchFlags.TEXT) {
 | 
			
		||||
        hostSetElementText(target, children as string)
 | 
			
		||||
      } else if (!optimized) {
 | 
			
		||||
        patchChildren(n1, n2, target, null, parentComponent, isSVG)
 | 
			
		||||
@ -524,10 +510,10 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
          : null)
 | 
			
		||||
        if (nextTarget != null) {
 | 
			
		||||
          // move content
 | 
			
		||||
          if (shapeFlag & TEXT_CHILDREN) {
 | 
			
		||||
          if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
 | 
			
		||||
            hostSetElementText(target, '')
 | 
			
		||||
            hostSetElementText(nextTarget, children as string)
 | 
			
		||||
          } else if (shapeFlag & ARRAY_CHILDREN) {
 | 
			
		||||
          } else if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
 | 
			
		||||
            for (let i = 0; i < (children as VNode[]).length; i++) {
 | 
			
		||||
              move((children as VNode[])[i], nextTarget, null)
 | 
			
		||||
            }
 | 
			
		||||
@ -591,7 +577,7 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
        resolveProps(instance, initialVNode.props, Component.props)
 | 
			
		||||
        resolveSlots(instance, initialVNode.children)
 | 
			
		||||
        // setup stateful
 | 
			
		||||
        if (initialVNode.shapeFlag & STATEFUL_COMPONENT) {
 | 
			
		||||
        if (initialVNode.shapeFlag & ShapeFlags.STATEFUL_COMPONENT) {
 | 
			
		||||
          setupStatefulComponent(instance)
 | 
			
		||||
        }
 | 
			
		||||
        const subTree = (instance.subTree = renderComponentRoot(instance))
 | 
			
		||||
@ -675,7 +661,7 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
    // fast path
 | 
			
		||||
    const { patchFlag, shapeFlag } = n2
 | 
			
		||||
    if (patchFlag) {
 | 
			
		||||
      if (patchFlag & KEYED) {
 | 
			
		||||
      if (patchFlag & PatchFlags.KEYED) {
 | 
			
		||||
        // this could be either fully-keyed or mixed (some keyed some not)
 | 
			
		||||
        // presence of patchFlag means children are guaranteed to be arrays
 | 
			
		||||
        patchKeyedChildren(
 | 
			
		||||
@ -688,7 +674,7 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
          optimized
 | 
			
		||||
        )
 | 
			
		||||
        return
 | 
			
		||||
      } else if (patchFlag & UNKEYED) {
 | 
			
		||||
      } else if (patchFlag & PatchFlags.UNKEYED) {
 | 
			
		||||
        // unkeyed
 | 
			
		||||
        patchUnkeyedChildren(
 | 
			
		||||
          c1 as VNode[],
 | 
			
		||||
@ -703,16 +689,16 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (shapeFlag & TEXT_CHILDREN) {
 | 
			
		||||
    if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
 | 
			
		||||
      // text children fast path
 | 
			
		||||
      if (prevShapeFlag & ARRAY_CHILDREN) {
 | 
			
		||||
      if (prevShapeFlag & ShapeFlags.ARRAY_CHILDREN) {
 | 
			
		||||
        unmountChildren(c1 as VNode[], parentComponent)
 | 
			
		||||
      }
 | 
			
		||||
      hostSetElementText(container, c2 as string)
 | 
			
		||||
    } else {
 | 
			
		||||
      if (prevShapeFlag & TEXT_CHILDREN) {
 | 
			
		||||
      if (prevShapeFlag & ShapeFlags.TEXT_CHILDREN) {
 | 
			
		||||
        hostSetElementText(container, '')
 | 
			
		||||
        if (shapeFlag & ARRAY_CHILDREN) {
 | 
			
		||||
        if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
 | 
			
		||||
          mountChildren(
 | 
			
		||||
            c2 as VNodeChildren,
 | 
			
		||||
            container,
 | 
			
		||||
@ -721,8 +707,8 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
            isSVG
 | 
			
		||||
          )
 | 
			
		||||
        }
 | 
			
		||||
      } else if (prevShapeFlag & ARRAY_CHILDREN) {
 | 
			
		||||
        if (shapeFlag & ARRAY_CHILDREN) {
 | 
			
		||||
      } else if (prevShapeFlag & ShapeFlags.ARRAY_CHILDREN) {
 | 
			
		||||
        if (shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
 | 
			
		||||
          // two arrays, cannot assume anything, do full diff
 | 
			
		||||
          patchKeyedChildren(
 | 
			
		||||
            c1 as VNode[],
 | 
			
		||||
@ -1020,7 +1006,7 @@ export function createRenderer(options: RendererOptions) {
 | 
			
		||||
        parentComponent,
 | 
			
		||||
        shouldRemoveChildren
 | 
			
		||||
      )
 | 
			
		||||
    } else if (vnode.shapeFlag & ARRAY_CHILDREN) {
 | 
			
		||||
    } else if (vnode.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
 | 
			
		||||
      unmountChildren(
 | 
			
		||||
        vnode.children as VNode[],
 | 
			
		||||
        parentComponent,
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,12 @@
 | 
			
		||||
// Types
 | 
			
		||||
export { VNode } from './vnode'
 | 
			
		||||
export { FunctionalComponent } from './component'
 | 
			
		||||
export { RendererOptions } from './createRenderer'
 | 
			
		||||
export { Slot, Slots } from './componentSlots'
 | 
			
		||||
export { PropType, ComponentPropsOptions } from './componentProps'
 | 
			
		||||
 | 
			
		||||
// API
 | 
			
		||||
export {
 | 
			
		||||
  VNode,
 | 
			
		||||
  openBlock,
 | 
			
		||||
  createBlock,
 | 
			
		||||
  createVNode,
 | 
			
		||||
@ -8,20 +15,14 @@ export {
 | 
			
		||||
  Fragment,
 | 
			
		||||
  Portal
 | 
			
		||||
} from './vnode'
 | 
			
		||||
 | 
			
		||||
export { createComponent, getCurrentInstance } from './component'
 | 
			
		||||
export { createRenderer } from './createRenderer'
 | 
			
		||||
export { nextTick } from './scheduler'
 | 
			
		||||
export {
 | 
			
		||||
  createComponent,
 | 
			
		||||
  getCurrentInstance,
 | 
			
		||||
  FunctionalComponent
 | 
			
		||||
} from './component'
 | 
			
		||||
export { createRenderer, RendererOptions } from './createRenderer'
 | 
			
		||||
export { Slot, Slots } from './componentSlots'
 | 
			
		||||
export { PropType, ComponentPropsOptions } from './componentProps'
 | 
			
		||||
 | 
			
		||||
export * from './apiReactivity'
 | 
			
		||||
export * from './apiWatch'
 | 
			
		||||
export * from './apiLifecycle'
 | 
			
		||||
export * from './apiInject'
 | 
			
		||||
export * from './patchFlags'
 | 
			
		||||
export * from './typeFlags'
 | 
			
		||||
 | 
			
		||||
// Flags
 | 
			
		||||
export { PublicPatchFlags as PatchFlags } from './patchFlags'
 | 
			
		||||
export { PublicShapeFlags as ShapeFlags } from './shapeFlags'
 | 
			
		||||
 | 
			
		||||
@ -13,8 +13,9 @@
 | 
			
		||||
// Check the `patchElement` function in './createRednerer.ts' to see how the
 | 
			
		||||
// flags are handled during diff.
 | 
			
		||||
 | 
			
		||||
export const enum PatchFlags {
 | 
			
		||||
  // Indicates an element with dynamic textContent (children fast path)
 | 
			
		||||
export const TEXT = 1
 | 
			
		||||
  TEXT = 1,
 | 
			
		||||
 | 
			
		||||
  // Indicates an element with dynamic class.
 | 
			
		||||
  // The compiler also pre-normalizes the :class binding:
 | 
			
		||||
@ -22,7 +23,7 @@ export const TEXT = 1
 | 
			
		||||
  // - ['foo', b] -> 'foo' + normalize(b)
 | 
			
		||||
  // - { a, b: c } -> (a ? a : '') + (b ? c : '')
 | 
			
		||||
  // - ['a', b, { c }] -> 'a' + normalize(b) + (c ? c : '')
 | 
			
		||||
export const CLASS = 1 << 1
 | 
			
		||||
  CLASS = 1 << 1,
 | 
			
		||||
 | 
			
		||||
  // Indicates an element with dynamic style
 | 
			
		||||
  // The compiler pre-compiles static string styles into static objects
 | 
			
		||||
@ -30,31 +31,45 @@ export const CLASS = 1 << 1
 | 
			
		||||
  // e.g. style="color: red" and :style="{ color: 'red' }" both get hoisted as
 | 
			
		||||
  //   const style = { color: 'red' }
 | 
			
		||||
  //   render() { return e('div', { style }) }
 | 
			
		||||
export const STYLE = 1 << 2
 | 
			
		||||
  STYLE = 1 << 2,
 | 
			
		||||
 | 
			
		||||
  // Indicates an element that has non-class/style dynamic props.
 | 
			
		||||
// Can also be on a component that has any dynamic props (includes class/style).
 | 
			
		||||
// when this flag is present, the vnode also has a dynamicProps array that
 | 
			
		||||
// contains the keys of the props that may change so the runtime can diff
 | 
			
		||||
// them faster (without having to worry about removed props)
 | 
			
		||||
export const PROPS = 1 << 3
 | 
			
		||||
  // Can also be on a component that has any dynamic props (includes
 | 
			
		||||
  // class/style). when this flag is present, the vnode also has a dynamicProps
 | 
			
		||||
  // array that contains the keys of the props that may change so the runtime
 | 
			
		||||
  // can diff them faster (without having to worry about removed props)
 | 
			
		||||
  PROPS = 1 << 3,
 | 
			
		||||
 | 
			
		||||
  // Indicates an element with props with dynamic keys. When keys change, a full
 | 
			
		||||
// diff is always needed to remove the old key. This flag is mutually exclusive
 | 
			
		||||
// with CLASS, STYLE and PROPS.
 | 
			
		||||
export const FULL_PROPS = 1 << 4
 | 
			
		||||
  // diff is always needed to remove the old key. This flag is mutually
 | 
			
		||||
  // exclusive with CLASS, STYLE and PROPS.
 | 
			
		||||
  FULL_PROPS = 1 << 4,
 | 
			
		||||
 | 
			
		||||
// Indicates a fragment or element with keyed or partially-keyed v-for children
 | 
			
		||||
export const KEYED = 1 << 5
 | 
			
		||||
  // Indicates a fragment or element with keyed or partially-keyed v-for
 | 
			
		||||
  // children
 | 
			
		||||
  KEYED = 1 << 5,
 | 
			
		||||
 | 
			
		||||
  // Indicates a fragment or element that contains unkeyed v-for children
 | 
			
		||||
export const UNKEYED = 1 << 6
 | 
			
		||||
  UNKEYED = 1 << 6,
 | 
			
		||||
 | 
			
		||||
  // Indicates a component with dynamic slots (e.g. slot that references a v-for
 | 
			
		||||
  // iterated value, or dynamic slot names).
 | 
			
		||||
  // Components with this flag are always force updated.
 | 
			
		||||
export const DYNAMIC_SLOTS = 1 << 7
 | 
			
		||||
  DYNAMIC_SLOTS = 1 << 7,
 | 
			
		||||
 | 
			
		||||
  // Indicates an element with ref. This includes static string refs because the
 | 
			
		||||
  // refs object is refreshed on each update and all refs need to set again.
 | 
			
		||||
export const REF = 1 << 8
 | 
			
		||||
  REF = 1 << 8
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// runtime object for public consumption
 | 
			
		||||
export const PublicPatchFlags = {
 | 
			
		||||
  TEXT: PatchFlags.TEXT,
 | 
			
		||||
  CLASS: PatchFlags.CLASS,
 | 
			
		||||
  STYLE: PatchFlags.STYLE,
 | 
			
		||||
  PROPS: PatchFlags.PROPS,
 | 
			
		||||
  FULL_PROPS: PatchFlags.FULL_PROPS,
 | 
			
		||||
  KEYED: PatchFlags.KEYED,
 | 
			
		||||
  UNKEYED: PatchFlags.UNKEYED,
 | 
			
		||||
  REF: PatchFlags.REF
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										20
									
								
								packages/runtime-core/src/shapeFlags.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								packages/runtime-core/src/shapeFlags.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,20 @@
 | 
			
		||||
// internally the const enum flags are used to avoid overhead of property
 | 
			
		||||
// access
 | 
			
		||||
export const enum ShapeFlags {
 | 
			
		||||
  ELEMENT = 1,
 | 
			
		||||
  FUNCTIONAL_COMPONENT = 1 << 1,
 | 
			
		||||
  STATEFUL_COMPONENT = 1 << 2,
 | 
			
		||||
  TEXT_CHILDREN = 1 << 3,
 | 
			
		||||
  ARRAY_CHILDREN = 1 << 4,
 | 
			
		||||
  SLOTS_CHILDREN = 1 << 5
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// but the flags are also exported as an actual object for external use
 | 
			
		||||
export const PublicShapeFlags = {
 | 
			
		||||
  ELEMENT: ShapeFlags.ELEMENT,
 | 
			
		||||
  FUNCTIONAL_COMPONENT: ShapeFlags.FUNCTIONAL_COMPONENT,
 | 
			
		||||
  STATEFUL_COMPONENT: ShapeFlags.STATEFUL_COMPONENT,
 | 
			
		||||
  TEXT_CHILDREN: ShapeFlags.TEXT_CHILDREN,
 | 
			
		||||
  ARRAY_CHILDREN: ShapeFlags.ARRAY_CHILDREN,
 | 
			
		||||
  SLOTS_CHILDREN: ShapeFlags.SLOTS_CHILDREN
 | 
			
		||||
}
 | 
			
		||||
@ -1,6 +0,0 @@
 | 
			
		||||
export const ELEMENT = 1
 | 
			
		||||
export const FUNCTIONAL_COMPONENT = 1 << 1
 | 
			
		||||
export const STATEFUL_COMPONENT = 1 << 2
 | 
			
		||||
export const TEXT_CHILDREN = 1 << 3
 | 
			
		||||
export const ARRAY_CHILDREN = 1 << 4
 | 
			
		||||
export const SLOTS_CHILDREN = 1 << 5
 | 
			
		||||
@ -1,16 +1,9 @@
 | 
			
		||||
import { isArray, isFunction, isString, isObject, EMPTY_ARR } from '@vue/shared'
 | 
			
		||||
import { ComponentInstance } from './component'
 | 
			
		||||
import { ComponentInstance, Data } from './component'
 | 
			
		||||
import { HostNode } from './createRenderer'
 | 
			
		||||
import { RawSlots } from './componentSlots'
 | 
			
		||||
import { CLASS } from './patchFlags'
 | 
			
		||||
import {
 | 
			
		||||
  ELEMENT,
 | 
			
		||||
  FUNCTIONAL_COMPONENT,
 | 
			
		||||
  STATEFUL_COMPONENT,
 | 
			
		||||
  TEXT_CHILDREN,
 | 
			
		||||
  ARRAY_CHILDREN,
 | 
			
		||||
  SLOTS_CHILDREN
 | 
			
		||||
} from './typeFlags'
 | 
			
		||||
import { PatchFlags } from './patchFlags'
 | 
			
		||||
import { ShapeFlags } from './shapeFlags'
 | 
			
		||||
 | 
			
		||||
export const Fragment = Symbol('Fragment')
 | 
			
		||||
export const Text = Symbol('Text')
 | 
			
		||||
@ -108,12 +101,12 @@ export function createVNode(
 | 
			
		||||
  props = props || null
 | 
			
		||||
 | 
			
		||||
  // encode the vnode type information into a bitmap
 | 
			
		||||
  const typeFlag = isString(type)
 | 
			
		||||
    ? ELEMENT
 | 
			
		||||
  const shapeFlag = isString(type)
 | 
			
		||||
    ? ShapeFlags.ELEMENT
 | 
			
		||||
    : isObject(type)
 | 
			
		||||
      ? STATEFUL_COMPONENT
 | 
			
		||||
      ? ShapeFlags.STATEFUL_COMPONENT
 | 
			
		||||
      : isFunction(type)
 | 
			
		||||
        ? FUNCTIONAL_COMPONENT
 | 
			
		||||
        ? ShapeFlags.FUNCTIONAL_COMPONENT
 | 
			
		||||
        : 0
 | 
			
		||||
 | 
			
		||||
  const vnode: VNode = {
 | 
			
		||||
@ -126,7 +119,7 @@ export function createVNode(
 | 
			
		||||
    el: null,
 | 
			
		||||
    anchor: null,
 | 
			
		||||
    target: null,
 | 
			
		||||
    shapeFlag: typeFlag,
 | 
			
		||||
    shapeFlag,
 | 
			
		||||
    patchFlag,
 | 
			
		||||
    dynamicProps,
 | 
			
		||||
    dynamicChildren: null
 | 
			
		||||
@ -138,7 +131,7 @@ export function createVNode(
 | 
			
		||||
  if (props !== null) {
 | 
			
		||||
    // class normalization only needed if the vnode isn't generated by
 | 
			
		||||
    // compiler-optimized code
 | 
			
		||||
    if (props.class != null && !(patchFlag & CLASS)) {
 | 
			
		||||
    if (props.class != null && !(patchFlag & PatchFlags.CLASS)) {
 | 
			
		||||
      props.class = normalizeClass(props.class)
 | 
			
		||||
    }
 | 
			
		||||
    if (props.style != null) {
 | 
			
		||||
@ -153,8 +146,8 @@ export function createVNode(
 | 
			
		||||
  if (
 | 
			
		||||
    shouldTrack &&
 | 
			
		||||
    (patchFlag ||
 | 
			
		||||
      typeFlag & STATEFUL_COMPONENT ||
 | 
			
		||||
      typeFlag & FUNCTIONAL_COMPONENT)
 | 
			
		||||
      shapeFlag & ShapeFlags.STATEFUL_COMPONENT ||
 | 
			
		||||
      shapeFlag & ShapeFlags.FUNCTIONAL_COMPONENT)
 | 
			
		||||
  ) {
 | 
			
		||||
    trackDynamicNode(vnode)
 | 
			
		||||
  }
 | 
			
		||||
@ -169,7 +162,7 @@ function trackDynamicNode(vnode: VNode) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function cloneVNode(vnode: VNode): VNode {
 | 
			
		||||
export function cloneVNode(vnode: VNode, extraProps?: Data): VNode {
 | 
			
		||||
  // TODO
 | 
			
		||||
  return vnode
 | 
			
		||||
}
 | 
			
		||||
@ -196,15 +189,15 @@ export function normalizeChildren(vnode: VNode, children: unknown) {
 | 
			
		||||
  if (children == null) {
 | 
			
		||||
    children = null
 | 
			
		||||
  } else if (isArray(children)) {
 | 
			
		||||
    type = ARRAY_CHILDREN
 | 
			
		||||
    type = ShapeFlags.ARRAY_CHILDREN
 | 
			
		||||
  } else if (typeof children === 'object') {
 | 
			
		||||
    type = SLOTS_CHILDREN
 | 
			
		||||
    type = ShapeFlags.SLOTS_CHILDREN
 | 
			
		||||
  } else if (isFunction(children)) {
 | 
			
		||||
    children = { default: children }
 | 
			
		||||
    type = SLOTS_CHILDREN
 | 
			
		||||
    type = ShapeFlags.SLOTS_CHILDREN
 | 
			
		||||
  } else {
 | 
			
		||||
    children = isString(children) ? children : children + ''
 | 
			
		||||
    type = TEXT_CHILDREN
 | 
			
		||||
    type = ShapeFlags.TEXT_CHILDREN
 | 
			
		||||
  }
 | 
			
		||||
  vnode.children = children as NormalizedChildren
 | 
			
		||||
  vnode.shapeFlag |= type
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user