Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
/corePublic

Commit37300fc

Browse files
authored
fix(v-once): setting hasOnce to current block only when in v-once (#12374)
close#12371
1 parentbee2f5e commit37300fc

File tree

8 files changed

+86
-15
lines changed

8 files changed

+86
-15
lines changed

‎packages/compiler-core/__tests__/transforms/__snapshots__/vOnce.spec.ts.snap‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ return function render(_ctx, _cache) {
88
const { setBlockTracking:_setBlockTracking, createElementVNode:_createElementVNode }=_Vue
99
1010
return_cache[0]|| (
11-
_setBlockTracking(-1),
11+
_setBlockTracking(-1,true),
1212
(_cache[0]=_createElementVNode("div", { id:foo },null,8/* PROPS*/, ["id"])).cacheIndex=0,
1313
_setBlockTracking(1),
1414
_cache[0]
@@ -28,7 +28,7 @@ return function render(_ctx, _cache) {
2828
2929
return (_openBlock(),_createElementBlock("div",null, [
3030
_cache[0]|| (
31-
_setBlockTracking(-1),
31+
_setBlockTracking(-1,true),
3232
(_cache[0]=_createVNode(_component_Comp, { id:foo },null,8/* PROPS*/, ["id"])).cacheIndex=0,
3333
_setBlockTracking(1),
3434
_cache[0]
@@ -47,7 +47,7 @@ return function render(_ctx, _cache) {
4747
4848
return (_openBlock(),_createElementBlock("div",null, [
4949
_cache[0]|| (
50-
_setBlockTracking(-1),
50+
_setBlockTracking(-1,true),
5151
(_cache[0]=_createElementVNode("div", { id:foo },null,8/* PROPS*/, ["id"])).cacheIndex=0,
5252
_setBlockTracking(1),
5353
_cache[0]
@@ -66,7 +66,7 @@ return function render(_ctx, _cache) {
6666
6767
return (_openBlock(),_createElementBlock("div",null, [
6868
_cache[0]|| (
69-
_setBlockTracking(-1),
69+
_setBlockTracking(-1,true),
7070
(_cache[0]=_renderSlot($slots,"default")).cacheIndex=0,
7171
_setBlockTracking(1),
7272
_cache[0]
@@ -85,7 +85,7 @@ return function render(_ctx, _cache) {
8585
8686
return (_openBlock(),_createElementBlock("div",null, [
8787
_cache[0]|| (
88-
_setBlockTracking(-1),
88+
_setBlockTracking(-1,true),
8989
(_cache[0]=_createElementVNode("div")).cacheIndex=0,
9090
_setBlockTracking(1),
9191
_cache[0]

‎packages/compiler-core/src/ast.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,7 @@ export interface CacheExpression extends Node {
418418
index:number
419419
value:JSChildNode
420420
needPauseTracking:boolean
421+
inVOnce:boolean
421422
needArraySpread:boolean
422423
}
423424

@@ -774,12 +775,14 @@ export function createCacheExpression(
774775
index:number,
775776
value:JSChildNode,
776777
needPauseTracking:boolean=false,
778+
inVOnce:boolean=false,
777779
):CacheExpression{
778780
return{
779781
type:NodeTypes.JS_CACHE_EXPRESSION,
780782
index,
781783
value,
782784
needPauseTracking:needPauseTracking,
785+
inVOnce,
783786
needArraySpread:false,
784787
loc:locStub,
785788
}

‎packages/compiler-core/src/codegen.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,9 @@ function genCacheExpression(node: CacheExpression, context: CodegenContext) {
10171017
push(`_cache[${node.index}] || (`)
10181018
if(needPauseTracking){
10191019
indent()
1020-
push(`${helper(SET_BLOCK_TRACKING)}(-1),`)
1020+
push(`${helper(SET_BLOCK_TRACKING)}(-1`)
1021+
if(node.inVOnce)push(`, true`)
1022+
push(`),`)
10211023
newline()
10221024
push(`(`)
10231025
}

‎packages/compiler-core/src/transform.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export interface TransformContext
116116
addIdentifiers(exp:ExpressionNode|string):void
117117
removeIdentifiers(exp:ExpressionNode|string):void
118118
hoist(exp:string|JSChildNode|ArrayExpression):SimpleExpressionNode
119-
cache(exp:JSChildNode,isVNode?:boolean):CacheExpression
119+
cache(exp:JSChildNode,isVNode?:boolean,inVOnce?:boolean):CacheExpression
120120
constantCache:WeakMap<TemplateChildNode,ConstantTypes>
121121

122122
// 2.x Compat only
@@ -297,11 +297,12 @@ export function createTransformContext(
297297
identifier.hoisted=exp
298298
returnidentifier
299299
},
300-
cache(exp,isVNode=false){
300+
cache(exp,isVNode=false,inVOnce=false){
301301
constcacheExp=createCacheExpression(
302302
context.cached.length,
303303
exp,
304304
isVNode,
305+
inVOnce,
305306
)
306307
context.cached.push(cacheExp)
307308
returncacheExp

‎packages/compiler-core/src/transforms/vOnce.ts‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ export const transformOnce: NodeTransform = (node, context) => {
1717
context.inVOnce=false
1818
constcur=context.currentNodeasElementNode|IfNode|ForNode
1919
if(cur.codegenNode){
20-
cur.codegenNode=context.cache(cur.codegenNode,true/* isVNode */)
20+
cur.codegenNode=context.cache(
21+
cur.codegenNode,
22+
true/* isVNode */,
23+
true/* inVOnce */,
24+
)
2125
}
2226
}
2327
}

‎packages/runtime-core/__tests__/rendererOptimizedMode.spec.ts‎

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
serializeInnerasinner,
1818
nextTick,
1919
nodeOps,
20+
onBeforeMount,
2021
onBeforeUnmount,
2122
onUnmounted,
2223
openBlock,
@@ -1199,7 +1200,7 @@ describe('renderer: optimized mode', () => {
11991200
createBlock('div',null,[
12001201
createVNode('div',null,[
12011202
cache[0]||
1202-
(setBlockTracking(-1),
1203+
(setBlockTracking(-1,true),
12031204
((cache[0]=createVNode('div',null,[
12041205
createVNode(Child),
12051206
])).cacheIndex=0),
@@ -1233,4 +1234,64 @@ describe('renderer: optimized mode', () => {
12331234
expect(inner(root)).toBe('<!--v-if-->')
12341235
expect(spyUnmounted).toHaveBeenCalledTimes(2)
12351236
})
1237+
1238+
// #12371
1239+
test('unmount children when the user calls a compiled slot',async()=>{
1240+
constbeforeMountSpy=vi.fn()
1241+
constbeforeUnmountSpy=vi.fn()
1242+
1243+
constChild={
1244+
setup(){
1245+
onBeforeMount(beforeMountSpy)
1246+
onBeforeUnmount(beforeUnmountSpy)
1247+
return()=>'child'
1248+
},
1249+
}
1250+
1251+
constWrapper={
1252+
setup(_:any,{ slots}:SetupContext){
1253+
return()=>(
1254+
openBlock(),
1255+
createElementBlock('section',null,[
1256+
(openBlock(),
1257+
createElementBlock('div',{key:1},[
1258+
createTextVNode(slots.header!() ?'foo' :'bar',1/* TEXT */),
1259+
renderSlot(slots,'content'),
1260+
])),
1261+
])
1262+
)
1263+
},
1264+
}
1265+
1266+
constshow=ref(false)
1267+
constapp=createApp({
1268+
render(){
1269+
returnshow.value
1270+
?(openBlock(),
1271+
createBlock(Wrapper,null,{
1272+
header:withCtx(()=>[createVNode({})]),
1273+
content:withCtx(()=>[createVNode(Child)]),
1274+
_:1,
1275+
}))
1276+
:createCommentVNode('v-if',true)
1277+
},
1278+
})
1279+
1280+
app.mount(root)
1281+
expect(inner(root)).toMatchInlineSnapshot(`"<!--v-if-->"`)
1282+
expect(beforeMountSpy).toHaveBeenCalledTimes(0)
1283+
expect(beforeUnmountSpy).toHaveBeenCalledTimes(0)
1284+
1285+
show.value=true
1286+
awaitnextTick()
1287+
expect(inner(root)).toMatchInlineSnapshot(
1288+
`"<section><div>foochild</div></section>"`,
1289+
)
1290+
expect(beforeMountSpy).toHaveBeenCalledTimes(1)
1291+
1292+
show.value=false
1293+
awaitnextTick()
1294+
expect(inner(root)).toBe('<!--v-if-->')
1295+
expect(beforeUnmountSpy).toHaveBeenCalledTimes(1)
1296+
})
12361297
})

‎packages/runtime-core/__tests__/vnode.spec.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,7 @@ describe('vnode', () => {
629629
constvnode=
630630
(openBlock(),
631631
createBlock('div',null,[
632-
setBlockTracking(-1),
632+
setBlockTracking(-1,true),
633633
(vnode1=(openBlock(),createBlock('div'))),
634634
setBlockTracking(1),
635635
vnode1,

‎packages/runtime-core/src/vnode.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ export let isBlockTreeEnabled = 1
301301
*
302302
* ``` js
303303
* _cache[1] || (
304-
* setBlockTracking(-1),
304+
* setBlockTracking(-1, true),
305305
* _cache[1] = createVNode(...),
306306
* setBlockTracking(1),
307307
* _cache[1]
@@ -310,11 +310,11 @@ export let isBlockTreeEnabled = 1
310310
*
311311
*@private
312312
*/
313-
exportfunctionsetBlockTracking(value:number):void{
313+
exportfunctionsetBlockTracking(value:number,inVOnce=false):void{
314314
isBlockTreeEnabled+=value
315-
if(value<0&&currentBlock){
315+
if(value<0&&currentBlock&&inVOnce){
316316
// mark current block so it doesn't take fast path and skip possible
317-
// nested componentsduriung unmount
317+
// nested componentsduring unmount
318318
currentBlock.hasOnce=true
319319
}
320320
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp