mirror of https://github.com/vuejs/core.git
parent
1904053f1f
commit
69ce3c7d75
|
|
@ -1040,4 +1040,57 @@ describe('hot module replacement', () => {
|
|||
|
||||
expect(serializeInner(root)).toBe('<div>bar</div>')
|
||||
})
|
||||
|
||||
// #14127
|
||||
test('update cached text nodes', async () => {
|
||||
const root = nodeOps.createElement('div')
|
||||
const appId = 'test-cached-text-nodes'
|
||||
const App: ComponentOptions = {
|
||||
__hmrId: appId,
|
||||
data() {
|
||||
return {
|
||||
count: 0,
|
||||
}
|
||||
},
|
||||
render: compileToFunction(
|
||||
`{{count}}
|
||||
<button @click="count++">++</button>
|
||||
static text`,
|
||||
),
|
||||
}
|
||||
createRecord(appId, App)
|
||||
render(h(App), root)
|
||||
expect(serializeInner(root)).toBe(`0 <button>++</button> static text`)
|
||||
|
||||
// trigger count update
|
||||
triggerEvent((root as any).children[2], 'click')
|
||||
await nextTick()
|
||||
expect(serializeInner(root)).toBe(`1 <button>++</button> static text`)
|
||||
|
||||
// trigger HMR update
|
||||
rerender(
|
||||
appId,
|
||||
compileToFunction(
|
||||
`{{count}}
|
||||
<button @click="count++">++</button>
|
||||
static text updated`,
|
||||
),
|
||||
)
|
||||
expect(serializeInner(root)).toBe(
|
||||
`1 <button>++</button> static text updated`,
|
||||
)
|
||||
|
||||
// trigger HMR update again
|
||||
rerender(
|
||||
appId,
|
||||
compileToFunction(
|
||||
`{{count}}
|
||||
<button @click="count++">++</button>
|
||||
static text updated2`,
|
||||
),
|
||||
)
|
||||
expect(serializeInner(root)).toBe(
|
||||
`1 <button>++</button> static text updated2`,
|
||||
)
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -500,7 +500,27 @@ function baseCreateRenderer(
|
|||
} else {
|
||||
const el = (n2.el = n1.el!)
|
||||
if (n2.children !== n1.children) {
|
||||
hostSetText(el, n2.children as string)
|
||||
// We don't inherit el for cached text nodes in `traverseStaticChildren`
|
||||
// to avoid retaining detached DOM nodes. However, the text node may be
|
||||
// changed during HMR. In this case we need to replace the old text node
|
||||
// with the new one.
|
||||
if (
|
||||
__DEV__ &&
|
||||
isHmrUpdating &&
|
||||
n2.patchFlag === PatchFlags.CACHED &&
|
||||
'__elIndex' in n1
|
||||
) {
|
||||
const childNodes = __TEST__
|
||||
? container.children
|
||||
: container.childNodes
|
||||
const newChild = hostCreateText(n2.children as string)
|
||||
const oldChild =
|
||||
childNodes[((n2 as any).__elIndex = (n1 as any).__elIndex)]
|
||||
hostInsert(newChild, container, oldChild)
|
||||
hostRemove(oldChild)
|
||||
} else {
|
||||
hostSetText(el, n2.children as string)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2496,12 +2516,17 @@ export function traverseStaticChildren(
|
|||
traverseStaticChildren(c1, c2)
|
||||
}
|
||||
// #6852 also inherit for text nodes
|
||||
if (
|
||||
c2.type === Text &&
|
||||
if (c2.type === Text) {
|
||||
// avoid cached text nodes retaining detached dom nodes
|
||||
c2.patchFlag !== PatchFlags.CACHED
|
||||
) {
|
||||
c2.el = c1.el
|
||||
if (c2.patchFlag !== PatchFlags.CACHED) {
|
||||
c2.el = c1.el
|
||||
} else {
|
||||
// cache the child index for HMR updates
|
||||
;(c2 as any).__elIndex =
|
||||
i +
|
||||
// take fragment start anchor into account
|
||||
(n1.type === Fragment ? 1 : 0)
|
||||
}
|
||||
}
|
||||
// #2324 also inherit for comment nodes, but not placeholders (e.g. v-if which
|
||||
// would have received .el during block patch)
|
||||
|
|
|
|||
Loading…
Reference in New Issue