feat(compiler/slot): bail out of optimization mode for non-compiled slots
This commit is contained in:
parent
05db2a9c6c
commit
227ad034f0
@ -58,7 +58,7 @@ export function shouldUpdateComponent(
|
|||||||
): boolean {
|
): boolean {
|
||||||
const { props: prevProps, children: prevChildren } = prevVNode
|
const { props: prevProps, children: prevChildren } = prevVNode
|
||||||
const { props: nextProps, children: nextChildren, patchFlag } = nextVNode
|
const { props: nextProps, children: nextChildren, patchFlag } = nextVNode
|
||||||
if (patchFlag) {
|
if (patchFlag > 0) {
|
||||||
if (patchFlag & PatchFlags.DYNAMIC_SLOTS) {
|
if (patchFlag & PatchFlags.DYNAMIC_SLOTS) {
|
||||||
// slot content that references values that might have changed,
|
// slot content that references values that might have changed,
|
||||||
// e.g. in a v-for
|
// e.g. in a v-for
|
||||||
|
@ -409,7 +409,7 @@ export function createRenderer<
|
|||||||
invokeDirectiveHook(newProps.vnodeBeforeUpdate, parentComponent, n2, n1)
|
invokeDirectiveHook(newProps.vnodeBeforeUpdate, parentComponent, n2, n1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (patchFlag) {
|
if (patchFlag > 0) {
|
||||||
// the presence of a patchFlag means this element's render code was
|
// the presence of a patchFlag means this element's render code was
|
||||||
// generated by the compiler and can take the fast path.
|
// generated by the compiler and can take the fast path.
|
||||||
// in this path old node and new node are guaranteed to have the same shape
|
// in this path old node and new node are guaranteed to have the same shape
|
||||||
@ -1227,9 +1227,12 @@ export function createRenderer<
|
|||||||
const prevShapeFlag = n1 ? n1.shapeFlag : 0
|
const prevShapeFlag = n1 ? n1.shapeFlag : 0
|
||||||
const c2 = n2.children
|
const c2 = n2.children
|
||||||
|
|
||||||
// fast path
|
|
||||||
const { patchFlag, shapeFlag } = n2
|
const { patchFlag, shapeFlag } = n2
|
||||||
if (patchFlag) {
|
if (patchFlag === PatchFlags.BAIL) {
|
||||||
|
optimized = false
|
||||||
|
}
|
||||||
|
// fast path
|
||||||
|
if (patchFlag > 0) {
|
||||||
if (patchFlag & PatchFlags.KEYED_FRAGMENT) {
|
if (patchFlag & PatchFlags.KEYED_FRAGMENT) {
|
||||||
// this could be either fully-keyed or mixed (some keyed some not)
|
// this could be either fully-keyed or mixed (some keyed some not)
|
||||||
// presence of patchFlag means children are guaranteed to be arrays
|
// presence of patchFlag means children are guaranteed to be arrays
|
||||||
|
@ -6,22 +6,24 @@ import {
|
|||||||
Fragment,
|
Fragment,
|
||||||
VNode
|
VNode
|
||||||
} from '../vnode'
|
} from '../vnode'
|
||||||
|
import { PatchFlags } from '@vue/shared'
|
||||||
|
|
||||||
export function renderSlot(
|
export function renderSlot(
|
||||||
slots: Record<string, Slot>,
|
slots: Record<string, Slot>,
|
||||||
key: string,
|
name: string,
|
||||||
props: any = {},
|
props: any = {},
|
||||||
// this is not a user-facing function, so the fallback is always generated by
|
// this is not a user-facing function, so the fallback is always generated by
|
||||||
// the compiler and gurunteed to be an array
|
// the compiler and gurunteed to be an array
|
||||||
fallback?: VNodeChildren
|
fallback?: VNodeChildren
|
||||||
): VNode {
|
): VNode {
|
||||||
const slot = slots[key]
|
const slot = slots[name]
|
||||||
return (
|
return (
|
||||||
openBlock(),
|
openBlock(),
|
||||||
createBlock(
|
createBlock(
|
||||||
Fragment,
|
Fragment,
|
||||||
{ key: props.key },
|
{ key: props.key },
|
||||||
slot ? slot(props) : fallback || []
|
slot ? slot(props) : fallback || [],
|
||||||
|
slots._compiled ? 0 : PatchFlags.BAIL
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,13 @@ export const enum PatchFlags {
|
|||||||
// Indicates a component with dynamic slots (e.g. slot that references a v-for
|
// Indicates a component with dynamic slots (e.g. slot that references a v-for
|
||||||
// iterated value, or dynamic slot names).
|
// iterated value, or dynamic slot names).
|
||||||
// Components with this flag are always force updated.
|
// Components with this flag are always force updated.
|
||||||
DYNAMIC_SLOTS = 1 << 8
|
DYNAMIC_SLOTS = 1 << 8,
|
||||||
|
|
||||||
|
// A special flag that indicates that the diffing algorithm should bail out
|
||||||
|
// of optimized mode. This is only on block fragments created by renderSlot()
|
||||||
|
// when encountering non-compiler generated slots (i.e. manually written
|
||||||
|
// render functions, which should always be fully diffed)
|
||||||
|
BAIL = -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// runtime object for public consumption
|
// runtime object for public consumption
|
||||||
@ -69,7 +75,8 @@ export const PublicPatchFlags = {
|
|||||||
FULL_PROPS: PatchFlags.FULL_PROPS,
|
FULL_PROPS: PatchFlags.FULL_PROPS,
|
||||||
KEYED_FRAGMENT: PatchFlags.KEYED_FRAGMENT,
|
KEYED_FRAGMENT: PatchFlags.KEYED_FRAGMENT,
|
||||||
UNKEYED_FRAGMENT: PatchFlags.UNKEYED_FRAGMENT,
|
UNKEYED_FRAGMENT: PatchFlags.UNKEYED_FRAGMENT,
|
||||||
DYNAMIC_SLOTS: PatchFlags.DYNAMIC_SLOTS
|
DYNAMIC_SLOTS: PatchFlags.DYNAMIC_SLOTS,
|
||||||
|
BAIL: PatchFlags.BAIL
|
||||||
}
|
}
|
||||||
|
|
||||||
// dev only flag -> name mapping
|
// dev only flag -> name mapping
|
||||||
@ -82,5 +89,6 @@ export const PatchFlagNames = {
|
|||||||
[PatchFlags.FULL_PROPS]: `FULL_PROPS`,
|
[PatchFlags.FULL_PROPS]: `FULL_PROPS`,
|
||||||
[PatchFlags.KEYED_FRAGMENT]: `KEYED_FRAGMENT`,
|
[PatchFlags.KEYED_FRAGMENT]: `KEYED_FRAGMENT`,
|
||||||
[PatchFlags.UNKEYED_FRAGMENT]: `UNKEYED_FRAGMENT`,
|
[PatchFlags.UNKEYED_FRAGMENT]: `UNKEYED_FRAGMENT`,
|
||||||
[PatchFlags.DYNAMIC_SLOTS]: `DYNAMIC_SLOTS`
|
[PatchFlags.DYNAMIC_SLOTS]: `DYNAMIC_SLOTS`,
|
||||||
|
[PatchFlags.BAIL]: `BAIL`
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user