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