@@ -26,13 +26,14 @@ export const dirRE = /^v-|^@|^:|^\./
2626export const forAliasRE = / ( [ \s \S ] * ?) \s + (?: i n | o f ) \s + ( [ \s \S ] * ) /
2727export const forIteratorRE = / , ( [ ^ , \} \] ] * ) (?: , ( [ ^ , \} \] ] * ) ) ? $ /
2828const stripParensRE = / ^ \( | \) $ / g
29+ const dynamicKeyRE = / ^ \[ .* \] $ /
2930
3031const argRE = / : ( .* ) $ /
3132export const bindRE = / ^ : | ^ \. | ^ v - b i n d : /
3233const propBindRE = / ^ \. /
3334const modifierRE = / \. [ ^ . ] + / g
3435
35- const scopedSlotShorthandRE = / ^ : ? \( . * \) $ /
36+ const slotRE = / ^ v - s l o t ( : | $ ) | ^ # /
3637
3738const lineBreakRE = / [ \r \n ] /
3839const whitespaceRE = / \s + / g
@@ -566,27 +567,7 @@ function processSlotContent (el) {
566567 true
567568 )
568569 }
569- el . slotScope = (
570- slotScope ||
571- getAndRemoveAttr ( el , 'slot-scope' )
572- )
573- if ( process . env . NEW_SLOT_SYNTAX ) {
574- // new in 2.6: slot-props and its shorthand works the same as slot-scope
575- // when used on <template> containers
576- el . slotScope = el . slotScope || getAndRemoveAttr ( el , 'slot-props' )
577- // 2.6 shorthand syntax
578- const shorthand = getAndRemoveAttrByRegex ( el , scopedSlotShorthandRE )
579- if ( shorthand ) {
580- if ( process . env . NODE_ENV !== 'production' && el . slotScope ) {
581- warn (
582- `Unexpected mixed usage of different slot syntaxes.` ,
583- el
584- )
585- }
586- el . slotTarget = getScopedSlotShorthandName ( shorthand )
587- el . slotScope = shorthand . value
588- }
589- }
570+ el . slotScope = slotScope || getAndRemoveAttr ( el , 'slot-scope' )
590571 } else if ( ( slotScope = getAndRemoveAttr ( el , 'slot-scope' ) ) ) {
591572 /* istanbul ignore if */
592573 if ( process . env . NODE_ENV !== 'production' && el . attrsMap [ 'v-for' ] ) {
@@ -599,36 +580,6 @@ function processSlotContent (el) {
599580 )
600581 }
601582 el . slotScope = slotScope
602- } else if ( process . env . NEW_SLOT_SYNTAX ) {
603- // 2.6: slot-props on component, denotes default slot
604- slotScope = getAndRemoveAttr ( el , 'slot-props' )
605- const shorthand = getAndRemoveAttrByRegex ( el , scopedSlotShorthandRE )
606- if ( slotScope || shorthand ) {
607- if ( process . env . NODE_ENV !== 'production' ) {
608- if ( ! maybeComponent ( el ) ) {
609- warn (
610- `slot-props cannot be used on non-component elements.` ,
611- el . rawAttrsMap [ 'slot-props' ] || el . rawAttrsMap [ '()' ]
612- )
613- }
614- if ( slotScope && shorthand ) {
615- warn (
616- `Unexpected mixed usage of different slot syntaxes.` ,
617- el
618- )
619- }
620- }
621- // add the component's children to its default slot
622- const slots = el . scopedSlots || ( el . scopedSlots = { } )
623- const target = shorthand ? getScopedSlotShorthandName ( shorthand ) : `"default"`
624- const slotContainer = slots [ target ] = createASTElement ( 'template' , [ ] , el )
625- slotContainer . children = el . children
626- slotContainer . slotScope = shorthand ? shorthand . value : slotScope
627- // remove children as they are returned from scopedSlots now
628- el . children = [ ]
629- // mark el non-plain so data gets generated
630- el . plain = false
631- }
632583 }
633584
634585 // slot="xxx"
@@ -641,14 +592,65 @@ function processSlotContent (el) {
641592 addAttr ( el , 'slot' , slotTarget , getRawBindingAttr ( el , 'slot' ) )
642593 }
643594 }
595+
596+ // 2.6 v-slot syntax
597+ if ( process . env . NEW_SLOT_SYNTAX ) {
598+ if ( el . tag === 'template' ) {
599+ // v-slot on <template>
600+ const slotBinding = getAndRemoveAttrByRegex ( el , slotRE )
601+ if ( slotBinding ) {
602+ if (
603+ process . env . NODE_ENV !== 'production' &&
604+ ( el . slotTarget || el . slotScope )
605+ ) {
606+ warn (
607+ `Unexpected mixed usage of different slot syntaxes.` ,
608+ el
609+ )
610+ }
611+ el . slotTarget = getSlotName ( slotBinding )
612+ el . slotScope = slotBinding . value
613+ }
614+ } else {
615+ // v-slot on component, denotes default slot
616+ const slotBinding = getAndRemoveAttrByRegex ( el , slotRE )
617+ if ( slotBinding ) {
618+ if ( process . env . NODE_ENV !== 'production' ) {
619+ if ( ! maybeComponent ( el ) ) {
620+ warn (
621+ `v-slot cannot be used on non-component elements.` ,
622+ slotBinding
623+ )
624+ }
625+ if ( el . slotScope || el . slotTarget ) {
626+ warn (
627+ `Unexpected mixed usage of different slot syntaxes.` ,
628+ el
629+ )
630+ }
631+ }
632+ // add the component's children to its default slot
633+ const slots = el . scopedSlots || ( el . scopedSlots = { } )
634+ const target = getSlotName ( slotBinding )
635+ const slotContainer = slots [ target ] = createASTElement ( 'template' , [ ] , el )
636+ slotContainer . children = el . children
637+ slotContainer . slotScope = slotBinding . value
638+ // remove children as they are returned from scopedSlots now
639+ el . children = [ ]
640+ // mark el non-plain so data gets generated
641+ el . plain = false
642+ }
643+ }
644+ }
644645}
645646
646- function getScopedSlotShorthandName ( { name } ) {
647- return name . charAt ( 0 ) === ':'
648- // dynamic :(name)
649- ? name . slice ( 2 , - 1 ) || `"default"`
650- // static (name)
651- : `"${ name . slice ( 1 , - 1 ) || `default` } "`
647+ function getSlotName ( { name } ) {
648+ name = name . replace ( slotRE , '' )
649+ return dynamicKeyRE . test ( name )
650+ // dynamic [name]
651+ ? name . slice ( 1 , - 1 )
652+ // static name
653+ : `"${ name || `default` } "`
652654}
653655
654656// handle <slot/> outlets
0 commit comments