MoveType,
RendererElement,
RendererNode,
- RendererOptions
+ RendererOptions,
+ traverseStaticChildren
} from '../renderer'
import { VNode, VNodeArrayChildren, VNodeProps } from '../vnode'
import { isString, ShapeFlags } from '@vue/shared'
// even in block tree mode we need to make sure all root-level nodes
// in the teleport inherit previous DOM references so that they can
// be moved in future patches.
- if (n2.shapeFlag & ShapeFlags.ARRAY_CHILDREN) {
- const oldChildren = n1.children as VNode[]
- const children = n2.children as VNode[]
- for (let i = 0; i < children.length; i++) {
- // only inherit for non-patched nodes (i.e. static ones)
- if (!children[i].el) {
- children[i].el = oldChildren[i].el
- }
- }
- }
+ traverseStaticChildren(n1, n2, true)
} else if (!optimized) {
patchChildren(
n1,
return hostNextSibling((vnode.anchor || vnode.el)!)
}
- /**
- * #1156
- * When a component is HMR-enabled, we need to make sure that all static nodes
- * inside a block also inherit the DOM element from the previous tree so that
- * HMR updates (which are full updates) can retrieve the element for patching.
- *
- * #2080
- * Inside keyed `template` fragment static children, if a fragment is moved,
- * the children will always moved so that need inherit el form previous nodes
- * to ensure correct moved position.
- */
- const traverseStaticChildren = (n1: VNode, n2: VNode, shallow = false) => {
- const ch1 = n1.children
- const ch2 = n2.children
- if (isArray(ch1) && isArray(ch2)) {
- for (let i = 0; i < ch1.length; i++) {
- // this is only called in the optimized path so array children are
- // guaranteed to be vnodes
- const c1 = ch1[i] as VNode
- const c2 = (ch2[i] = cloneIfMounted(ch2[i] as VNode))
- if (c2.shapeFlag & ShapeFlags.ELEMENT && !c2.dynamicChildren) {
- if (c2.patchFlag <= 0 || c2.patchFlag === PatchFlags.HYDRATE_EVENTS) {
- c2.el = c1.el
- }
- if (!shallow) traverseStaticChildren(c1, c2)
- }
- if (__DEV__ && c2.type === Comment) {
- c2.el = c1.el
- }
- }
- }
- }
-
const render: RootRenderFunction = (vnode, container) => {
if (vnode == null) {
if (container._vnode) {
])
}
+/**
+ * #1156
+ * When a component is HMR-enabled, we need to make sure that all static nodes
+ * inside a block also inherit the DOM element from the previous tree so that
+ * HMR updates (which are full updates) can retrieve the element for patching.
+ *
+ * #2080
+ * Inside keyed `template` fragment static children, if a fragment is moved,
+ * the children will always moved so that need inherit el form previous nodes
+ * to ensure correct moved position.
+ */
+export function traverseStaticChildren(n1: VNode, n2: VNode, shallow = false) {
+ const ch1 = n1.children
+ const ch2 = n2.children
+ if (isArray(ch1) && isArray(ch2)) {
+ for (let i = 0; i < ch1.length; i++) {
+ // this is only called in the optimized path so array children are
+ // guaranteed to be vnodes
+ const c1 = ch1[i] as VNode
+ let c2 = ch2[i] as VNode
+ if (c2.shapeFlag & ShapeFlags.ELEMENT && !c2.dynamicChildren) {
+ if (c2.patchFlag <= 0 || c2.patchFlag === PatchFlags.HYDRATE_EVENTS) {
+ c2 = ch2[i] = cloneIfMounted(ch2[i] as VNode)
+ c2.el = c1.el
+ }
+ if (!shallow) traverseStaticChildren(c1, c2)
+ }
+ // also inherit for comment nodes, but not placeholders (e.g. v-if which
+ // would have received .el during block patch)
+ if (__DEV__ && c2.type === Comment && !c2.el) {
+ c2.el = c1.el
+ }
+ }
+ }
+}
+
// https://en.wikipedia.org/wiki/Longest_increasing_subsequence
function getSequence(arr: number[]): number[] {
const p = arr.slice()