File tree Expand file tree Collapse file tree 6 files changed +61
-49
lines changed Expand file tree Collapse file tree 6 files changed +61
-49
lines changed Original file line number Diff line number Diff line change @@ -93,6 +93,8 @@ declare interface Component {
93
93
_f : ( id : string ) = > Function ;
94
94
// renderList
95
95
_l : ( val : any , render : Function ) = > ?Array < VNode > ;
96
+ // renderSlot
97
+ _t : ( name : string , fallback : ?Array < VNode > ) => ?Array < VNode > ;
96
98
// apply v-bind object
97
99
_b : ( vnode : VNodeWithData , value : any ) = > void ;
98
100
// retrive custom keyCode
Original file line number Diff line number Diff line change @@ -221,11 +221,11 @@ function genText (text: ASTText | ASTExpression): string {
221
221
}
222
222
223
223
function genSlot ( el : ASTElement ) : string {
224
- const slot = `$slots[ ${ el . slotName || '"default"' } ]`
224
+ const slotName = el . slotName || '"default"'
225
225
const children = genChildren ( el )
226
226
return children
227
- ? `(${ slot } || ${ children } )`
228
- : slot
227
+ ? `_t (${ slotName } , ${ children } )`
228
+ : `_t( ${ slotName } )`
229
229
}
230
230
231
231
function genComponent ( el : any ) : string {
Original file line number Diff line number Diff line change @@ -34,7 +34,6 @@ let preTransforms
34
34
let transforms
35
35
let postTransforms
36
36
let delimiters
37
- let seenSlots : any
38
37
39
38
/**
40
39
* Convert HTML string to AST.
@@ -51,7 +50,6 @@ export function parse (
51
50
transforms = pluckModuleFunction ( options . modules , 'transformNode' )
52
51
postTransforms = pluckModuleFunction ( options . modules , 'postTransformNode' )
53
52
delimiters = options . delimiters
54
- seenSlots = Object . create ( null )
55
53
const stack = [ ]
56
54
const preserveWhitespace = options . preserveWhitespace !== false
57
55
let root
@@ -326,25 +324,7 @@ function processOnce (el) {
326
324
327
325
function processSlot ( el ) {
328
326
if ( el . tag === 'slot' ) {
329
- if ( process . env . NODE_ENV !== 'production' ) {
330
- if ( ! el . attrsMap [ ':name' ] && ! el . attrsMap [ 'v-bind:name' ] && checkInFor ( el ) ) {
331
- warn (
332
- 'Static <slot> found inside v-for: they will not render correctly. ' +
333
- 'Render the list in parent scope and use a single <slot> instead.'
334
- )
335
- }
336
- }
337
327
el . slotName = getBindingAttr ( el , 'name' )
338
- if ( process . env . NODE_ENV !== 'production' ) {
339
- const name = el . slotName
340
- if ( seenSlots [ name ] ) {
341
- warn (
342
- `Duplicate ${ name ? `<slot> with name ${ name } ` : `default <slot>` } ` +
343
- `found in the same template.`
344
- )
345
- }
346
- seenSlots [ name ] = true
347
- }
348
328
} else {
349
329
const slotTarget = getBindingAttr ( el , 'slot' )
350
330
if ( slotTarget ) {
Original file line number Diff line number Diff line change @@ -36,13 +36,6 @@ export function renderMixin (Vue: Class<Component>) {
36
36
_parentVnode
37
37
} = vm . $options
38
38
39
- if ( vm . _isMounted ) {
40
- // clone slot nodes on re-renders
41
- for ( const key in vm . $slots ) {
42
- vm . $slots [ key ] = cloneVNodes ( vm . $slots [ key ] )
43
- }
44
- }
45
-
46
39
if ( staticRenderFns && ! vm . _staticTrees ) {
47
40
vm . _staticTrees = [ ]
48
41
}
@@ -155,6 +148,30 @@ export function renderMixin (Vue: Class<Component>) {
155
148
return ret
156
149
}
157
150
151
+ // renderSlot
152
+ Vue . prototype . _t = function (
153
+ name : string ,
154
+ fallback : ?Array < VNode >
155
+ ) : ?Array < VNode > {
156
+ let slotNodes = this . $slots [ name ]
157
+ if ( slotNodes ) {
158
+ // warn duplicate slot usage
159
+ if ( process . env . NODE_ENV !== 'production' ) {
160
+ slotNodes . _rendered && warn (
161
+ `Duplicate presense of slot "${ name } " found in the same render tree ` +
162
+ `- this will likely cause render errors.` ,
163
+ this
164
+ )
165
+ slotNodes . _rendered = true
166
+ }
167
+ // clone slot nodes on re-renders
168
+ if ( this . _isMounted ) {
169
+ slotNodes = cloneVNodes ( slotNodes )
170
+ }
171
+ }
172
+ return slotNodes || fallback
173
+ }
174
+
158
175
// apply v-bind object
159
176
Vue . prototype . _b = function bindProps (
160
177
vnode : VNodeWithData ,
Original file line number Diff line number Diff line change @@ -458,28 +458,41 @@ describe('Component slot', () => {
458
458
it ( 'warn duplicate slots' , ( ) => {
459
459
new Vue ( {
460
460
template : `<div>
461
- <slot></slot><slot></slot>
462
- <slot name="a"></slot><slot name="a"></slot>
463
- </div>`
461
+ <test>
462
+ <div>foo</div>
463
+ <div slot="a">bar</div>
464
+ </test>
465
+ </div>` ,
466
+ components : {
467
+ test : {
468
+ template : `<div>
469
+ <slot></slot><slot></slot>
470
+ <div v-for="i in 3"><slot name="a"></slot></div>
471
+ </div>`
472
+ }
473
+ }
464
474
} ) . $mount ( )
465
- expect ( 'Duplicate default < slot> ' ) . toHaveBeenWarned ( )
466
- expect ( 'Duplicate <slot> with name "a"' ) . toHaveBeenWarned ( )
475
+ expect ( 'Duplicate presense of slot "default" ' ) . toHaveBeenWarned ( )
476
+ expect ( 'Duplicate presense of slot "a"' ) . toHaveBeenWarned ( )
467
477
} )
468
478
469
- it ( 'warn static slot inside v-for' , ( ) => {
470
- new Vue ( {
471
- template : `<div>
472
- <div v-for="i in 1"><slot :name="'test' + i"></slot></div>
473
- </div>`
474
- } ) . $mount ( )
475
- expect ( 'Static <slot> found inside v-for' ) . not . toHaveBeenWarned ( )
476
-
479
+ it ( 'should not warn valid conditional slots' , ( ) => {
477
480
new Vue ( {
478
481
template : `<div>
479
- <div v-for="i in 1"><slot></slot></div>
480
- </div>`
482
+ <test>
483
+ <div>foo</div>
484
+ </test>
485
+ </div>` ,
486
+ components : {
487
+ test : {
488
+ template : `<div>
489
+ <slot v-if="true"></slot>
490
+ <slot v-else></slot>
491
+ </div>`
492
+ }
493
+ }
481
494
} ) . $mount ( )
482
- expect ( 'Static <slot> found inside v-for' ) . toHaveBeenWarned ( )
495
+ expect ( 'Duplicate presense of slot "default"' ) . not . toHaveBeenWarned ( )
483
496
} )
484
497
485
498
// #3518
Original file line number Diff line number Diff line change @@ -98,21 +98,21 @@ describe('codegen', () => {
98
98
it ( 'generate single slot' , ( ) => {
99
99
assertCodegen (
100
100
'<slot></slot>' ,
101
- `with(this){return $slots[ "default"] }`
101
+ `with(this){return _t( "default") }`
102
102
)
103
103
} )
104
104
105
105
it ( 'generate named slot' , ( ) => {
106
106
assertCodegen (
107
107
'<slot name="one"></slot>' ,
108
- `with(this){return $slots[ "one"] }`
108
+ `with(this){return _t( "one") }`
109
109
)
110
110
} )
111
111
112
112
it ( 'generate slot fallback content' , ( ) => {
113
113
assertCodegen (
114
114
'<slot><div>hi</div></slot>' ,
115
- `with(this){return ($slots[ "default"]|| [_m(0)])}` ,
115
+ `with(this){return _t( "default", [_m(0)])}` ,
116
116
[ `with(this){return _h('div',["hi"])}` ]
117
117
)
118
118
} )
You can’t perform that action at this time.
0 commit comments