wip: include children type in shapeFlag
This commit is contained in:
parent
2f1f6b4355
commit
6d90ba28d3
@ -14,7 +14,7 @@ import {
|
||||
createComponentInstance,
|
||||
setupStatefulComponent
|
||||
} from './component'
|
||||
import { isString, isArray, EMPTY_OBJ, EMPTY_ARR } from '@vue/shared'
|
||||
import { isString, EMPTY_OBJ, EMPTY_ARR } from '@vue/shared'
|
||||
import {
|
||||
TEXT,
|
||||
CLASS,
|
||||
@ -28,7 +28,13 @@ import { queueJob, queuePostFlushCb, flushPostFlushCbs } from './scheduler'
|
||||
import { effect, stop, ReactiveEffectOptions } from '@vue/observer'
|
||||
import { resolveProps } from './componentProps'
|
||||
import { resolveSlots } from './componentSlots'
|
||||
import { ELEMENT, STATEFUL_COMPONENT, FUNCTIONAL_COMPONENT } from './shapeFlags'
|
||||
import {
|
||||
ELEMENT,
|
||||
STATEFUL_COMPONENT,
|
||||
FUNCTIONAL_COMPONENT,
|
||||
TEXT_CHILDREN,
|
||||
ARRAY_CHILDREN
|
||||
} from './shapeFlags'
|
||||
|
||||
const prodEffectOptions = {
|
||||
scheduler: queueJob
|
||||
@ -193,15 +199,16 @@ export function createRenderer(options: RendererOptions) {
|
||||
|
||||
function mountElement(vnode: VNode, container: HostNode, anchor?: HostNode) {
|
||||
const el = (vnode.el = hostCreateElement(vnode.type as string))
|
||||
if (vnode.props != null) {
|
||||
for (const key in vnode.props) {
|
||||
hostPatchProp(el, key, vnode.props[key], null, false)
|
||||
const { props, shapeFlag } = vnode
|
||||
if (props != null) {
|
||||
for (const key in props) {
|
||||
hostPatchProp(el, key, props[key], null, false)
|
||||
}
|
||||
}
|
||||
if (isString(vnode.children)) {
|
||||
hostSetElementText(el, vnode.children)
|
||||
} else if (isArray(vnode.children)) {
|
||||
mountChildren(vnode.children, el)
|
||||
if (shapeFlag & TEXT_CHILDREN) {
|
||||
hostSetElementText(el, vnode.children as string)
|
||||
} else if (shapeFlag & ARRAY_CHILDREN) {
|
||||
mountChildren(vnode.children as VNodeChildren, el)
|
||||
}
|
||||
hostInsert(el, container, anchor)
|
||||
}
|
||||
@ -374,16 +381,16 @@ export function createRenderer(options: RendererOptions) {
|
||||
optimized?: boolean
|
||||
) {
|
||||
const targetSelector = n2.props && n2.props.target
|
||||
const { patchFlag, shapeFlag, children } = n2
|
||||
if (n1 == null) {
|
||||
const children = n2.children
|
||||
const target = (n2.target = isString(targetSelector)
|
||||
? hostQuerySelector(targetSelector)
|
||||
: null)
|
||||
if (target != null) {
|
||||
if (isString(children)) {
|
||||
hostSetElementText(target, children)
|
||||
} else if (isArray(children)) {
|
||||
mountChildren(children, target)
|
||||
if (shapeFlag & TEXT_CHILDREN) {
|
||||
hostSetElementText(target, children as string)
|
||||
} else if (shapeFlag & ARRAY_CHILDREN) {
|
||||
mountChildren(children as VNodeChildren, target)
|
||||
}
|
||||
} else {
|
||||
// TODO warn missing or invalid target
|
||||
@ -391,8 +398,8 @@ export function createRenderer(options: RendererOptions) {
|
||||
} else {
|
||||
// update content
|
||||
const target = (n2.target = n1.target)
|
||||
if (n2.patchFlag === TEXT) {
|
||||
hostSetElementText(target, n2.children as string)
|
||||
if (patchFlag === TEXT) {
|
||||
hostSetElementText(target, children as string)
|
||||
} else if (!optimized) {
|
||||
patchChildren(n1, n2, target)
|
||||
}
|
||||
@ -403,13 +410,12 @@ export function createRenderer(options: RendererOptions) {
|
||||
: null)
|
||||
if (nextTarget != null) {
|
||||
// move content
|
||||
const children = n2.children
|
||||
if (isString(children)) {
|
||||
if (shapeFlag & TEXT_CHILDREN) {
|
||||
hostSetElementText(target, '')
|
||||
hostSetElementText(nextTarget, children)
|
||||
} else if (isArray(children)) {
|
||||
for (let i = 0; i < children.length; i++) {
|
||||
move(children[i] as VNode, nextTarget, null)
|
||||
hostSetElementText(nextTarget, children as string)
|
||||
} else if (shapeFlag & ARRAY_CHILDREN) {
|
||||
for (let i = 0; i < (children as VNode[]).length; i++) {
|
||||
move((children as VNode[])[i], nextTarget, null)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -516,10 +522,11 @@ export function createRenderer(options: RendererOptions) {
|
||||
optimized?: boolean
|
||||
) {
|
||||
const c1 = n1 && n1.children
|
||||
const prevShapeFlag = n1 ? n1.shapeFlag : 0
|
||||
const c2 = n2.children
|
||||
|
||||
// fast path
|
||||
const { patchFlag } = n2
|
||||
const { patchFlag, shapeFlag } = n2
|
||||
if (patchFlag) {
|
||||
if (patchFlag & KEYED) {
|
||||
// this could be either fully-keyed or mixed (some keyed some not)
|
||||
@ -545,22 +552,28 @@ export function createRenderer(options: RendererOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
if (isString(c2)) {
|
||||
if (shapeFlag & TEXT_CHILDREN) {
|
||||
// text children fast path
|
||||
if (isArray(c1)) {
|
||||
if (prevShapeFlag & ARRAY_CHILDREN) {
|
||||
unmountChildren(c1 as VNode[])
|
||||
}
|
||||
hostSetElementText(container, c2)
|
||||
hostSetElementText(container, c2 as string)
|
||||
} else {
|
||||
if (isString(c1)) {
|
||||
if (prevShapeFlag & TEXT_CHILDREN) {
|
||||
hostSetElementText(container, '')
|
||||
if (isArray(c2)) {
|
||||
mountChildren(c2, container, anchor)
|
||||
if (shapeFlag & ARRAY_CHILDREN) {
|
||||
mountChildren(c2 as VNodeChildren, container, anchor)
|
||||
}
|
||||
} else if (isArray(c1)) {
|
||||
if (isArray(c2)) {
|
||||
} else if (prevShapeFlag & ARRAY_CHILDREN) {
|
||||
if (shapeFlag & ARRAY_CHILDREN) {
|
||||
// two arrays, cannot assume anything, do full diff
|
||||
patchKeyedChildren(c1 as VNode[], c2, container, anchor, optimized)
|
||||
patchKeyedChildren(
|
||||
c1 as VNode[],
|
||||
c2 as VNodeChildren,
|
||||
container,
|
||||
anchor,
|
||||
optimized
|
||||
)
|
||||
} else {
|
||||
// c2 is null in this case
|
||||
unmountChildren(c1 as VNode[], true)
|
||||
@ -791,7 +804,7 @@ export function createRenderer(options: RendererOptions) {
|
||||
const shouldRemoveChildren = vnode.type === Fragment && doRemove
|
||||
if (vnode.dynamicChildren != null) {
|
||||
unmountChildren(vnode.dynamicChildren, shouldRemoveChildren)
|
||||
} else if (isArray(vnode.children)) {
|
||||
} else if (vnode.shapeFlag & ARRAY_CHILDREN) {
|
||||
unmountChildren(vnode.children as VNode[], shouldRemoveChildren)
|
||||
}
|
||||
if (doRemove) {
|
||||
|
@ -1,3 +1,6 @@
|
||||
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
|
||||
|
@ -3,7 +3,14 @@ import { ComponentInstance } from './component'
|
||||
import { HostNode } from './createRenderer'
|
||||
import { RawSlots } from './componentSlots'
|
||||
import { CLASS } from './patchFlags'
|
||||
import { ELEMENT, FUNCTIONAL_COMPONENT, STATEFUL_COMPONENT } from './shapeFlags'
|
||||
import {
|
||||
ELEMENT,
|
||||
FUNCTIONAL_COMPONENT,
|
||||
STATEFUL_COMPONENT,
|
||||
TEXT_CHILDREN,
|
||||
ARRAY_CHILDREN,
|
||||
SLOTS_CHILDREN
|
||||
} from './shapeFlags'
|
||||
|
||||
export const Fragment = Symbol('Fragment')
|
||||
export const Text = Symbol('Text')
|
||||
@ -95,8 +102,10 @@ export function createVNode(
|
||||
): VNode {
|
||||
// Allow passing 0 for props, this can save bytes on generated code.
|
||||
props = props || null
|
||||
// normalize children
|
||||
children = normalizeChildren(children) as NormalizedChildren
|
||||
|
||||
const shapeFlag = isString(type)
|
||||
const typeFlag = isString(type)
|
||||
? ELEMENT
|
||||
: isFunction(type)
|
||||
? FUNCTIONAL_COMPONENT
|
||||
@ -104,16 +113,24 @@ export function createVNode(
|
||||
? STATEFUL_COMPONENT
|
||||
: 0
|
||||
|
||||
const childFlag = isString(children)
|
||||
? TEXT_CHILDREN
|
||||
: isArray(children)
|
||||
? ARRAY_CHILDREN
|
||||
: isObject(children)
|
||||
? SLOTS_CHILDREN
|
||||
: 0
|
||||
|
||||
const vnode: VNode = {
|
||||
type,
|
||||
props,
|
||||
key: props && props.key,
|
||||
children: normalizeChildren(children),
|
||||
children,
|
||||
component: null,
|
||||
el: null,
|
||||
anchor: null,
|
||||
target: null,
|
||||
shapeFlag,
|
||||
shapeFlag: typeFlag | childFlag,
|
||||
patchFlag,
|
||||
dynamicProps,
|
||||
dynamicChildren: null
|
||||
@ -138,8 +155,8 @@ export function createVNode(
|
||||
if (
|
||||
shouldTrack &&
|
||||
(patchFlag ||
|
||||
shapeFlag & STATEFUL_COMPONENT ||
|
||||
shapeFlag & FUNCTIONAL_COMPONENT)
|
||||
typeFlag & STATEFUL_COMPONENT ||
|
||||
typeFlag & FUNCTIONAL_COMPONENT)
|
||||
) {
|
||||
trackDynamicNode(vnode)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user