@@ -10,6 +10,7 @@ let transforms
1010let dataGenFns
1111let platformDirectives
1212let staticRenderFns
13+ let onceCount
1314let currentOptions
1415
1516export function generate (
@@ -22,13 +23,16 @@ export function generate (
2223 // save previous staticRenderFns so generate calls can be nested
2324 const prevStaticRenderFns : Array < string > = staticRenderFns
2425 const currentStaticRenderFns : Array < string > = staticRenderFns = [ ]
26+ const prevOnceCount = onceCount
27+ onceCount = 0
2528 currentOptions = options
2629 warn = options . warn || baseWarn
2730 transforms = pluckModuleFunction ( options . modules , 'transformCode' )
2831 dataGenFns = pluckModuleFunction ( options . modules , 'genData' )
2932 platformDirectives = options . directives || { }
3033 const code = ast ? genElement ( ast ) : '_h("div")'
3134 staticRenderFns = prevStaticRenderFns
35+ onceCount = prevOnceCount
3236 return {
3337 render : `with(this){return ${ code } }` ,
3438 staticRenderFns : currentStaticRenderFns
@@ -37,10 +41,9 @@ export function generate (
3741
3842function genElement ( el : ASTElement ) : string {
3943 if ( el . staticRoot && ! el . staticProcessed ) {
40- // hoist static sub-trees out
41- el . staticProcessed = true
42- staticRenderFns . push ( `with(this){return ${ genElement ( el ) } }` )
43- return `_m(${ staticRenderFns . length - 1 } ${ el . staticInFor ? ',true' : '' } )`
44+ return genStatic ( el )
45+ } else if ( el . once && ! el . onceProcessed ) {
46+ return genOnce ( el )
4447 } else if ( el . for && ! el . forProcessed ) {
4548 return genFor ( el )
4649 } else if ( el . if && ! el . ifProcessed ) {
@@ -72,6 +75,38 @@ function genElement (el: ASTElement): string {
7275 }
7376}
7477
78+ // hoist static sub-trees out
79+ function genStatic ( el : ASTElement ) : string {
80+ el . staticProcessed = true
81+ staticRenderFns . push ( `with(this){return ${ genElement ( el ) } }` )
82+ return `_m(${ staticRenderFns . length - 1 } ${ el . staticInFor ? ',true' : '' } )`
83+ }
84+
85+ // v-once
86+ function genOnce ( el : ASTElement ) : string {
87+ el . onceProcessed = true
88+ if ( el . staticInFor ) {
89+ let key = ''
90+ let parent = el . parent
91+ while ( parent ) {
92+ if ( parent . for ) {
93+ key = parent . key
94+ break
95+ }
96+ parent = parent . parent
97+ }
98+ if ( ! key ) {
99+ process . env . NODE_ENV !== 'production' && warn (
100+ `v-once can only be used inside v-for that is keyed. `
101+ )
102+ return genElement ( el )
103+ }
104+ return `_o(${ genElement ( el ) } ,${ onceCount ++ } ${ key ? `,${ key } ` : `` } )`
105+ } else {
106+ return genStatic ( el )
107+ }
108+ }
109+
75110function genIf ( el : any ) : string {
76111 const exp = el . if
77112 el . ifProcessed = true // avoid recursion
0 commit comments