Skip to content

Commit 6a2994e

Browse files
committed
revert: feat: support scoped-slot usage with $slot
This reverts commit 7988a55.
1 parent 6fe07eb commit 6a2994e

File tree

5 files changed

+10
-175
lines changed

5 files changed

+10
-175
lines changed

flow/compiler.js

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ declare type ASTDirective = {
8585
end?: number;
8686
};
8787

88-
declare type ASTNode = ASTElement | ASTText | ASTExpression
88+
declare type ASTNode = ASTElement | ASTText | ASTExpression;
8989

9090
declare type ASTElement = {
9191
type: 1;
@@ -167,9 +167,6 @@ declare type ASTElement = {
167167

168168
// weex specific
169169
appendAsTree?: boolean;
170-
171-
// 2.6 $slot check
172-
has$Slot?: boolean
173170
};
174171

175172
declare type ASTExpression = {
@@ -182,8 +179,6 @@ declare type ASTExpression = {
182179
ssrOptimizability?: number;
183180
start?: number;
184181
end?: number;
185-
// 2.6 $slot check
186-
has$Slot?: boolean
187182
};
188183

189184
declare type ASTText = {
@@ -195,8 +190,6 @@ declare type ASTText = {
195190
ssrOptimizability?: number;
196191
start?: number;
197192
end?: number;
198-
// 2.6 $slot check
199-
has$Slot?: boolean
200193
};
201194

202195
// SFC-parser related declarations

src/compiler/codegen/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export class CodegenState {
2727
this.dataGenFns = pluckModuleFunction(options.modules, 'genData')
2828
this.directives = extend(extend({}, baseDirectives), options.directives)
2929
const isReservedTag = options.isReservedTag || no
30-
this.maybeComponent = (el: ASTElement) => !!el.component || !isReservedTag(el.tag)
30+
this.maybeComponent = (el: ASTElement) => el.component || !isReservedTag(el.tag)
3131
this.onceId = 0
3232
this.staticRenderFns = []
3333
this.pre = false

src/compiler/optimizer.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export function optimize (root: ?ASTElement, options: CompilerOptions) {
3030

3131
function genStaticKeys (keys: string): Function {
3232
return makeMap(
33-
'type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap,has$Slot' +
33+
'type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap' +
3434
(keys ? ',' + keys : '')
3535
)
3636
}
@@ -43,7 +43,6 @@ function markStatic (node: ASTNode) {
4343
// 2. static slot content fails for hot-reloading
4444
if (
4545
!isPlatformReservedTag(node.tag) &&
46-
!node.component &&
4746
node.tag !== 'slot' &&
4847
node.attrsMap['inline-template'] == null
4948
) {

src/compiler/parser/index.js

Lines changed: 7 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { parseHTML } from './html-parser'
55
import { parseText } from './text-parser'
66
import { parseFilters } from './filter-parser'
77
import { genAssignmentCode } from '../directives/model'
8-
import { extend, cached, no, camelize, hyphenate, hasOwn } from 'shared/util'
8+
import { extend, cached, no, camelize, hyphenate } from 'shared/util'
99
import { isIE, isEdge, isServerRendering } from 'core/util/env'
1010

1111
import {
@@ -45,7 +45,6 @@ let postTransforms
4545
let platformIsPreTag
4646
let platformMustUseProp
4747
let platformGetTagNamespace
48-
let maybeComponent
4948

5049
export function createASTElement (
5150
tag: string,
@@ -75,8 +74,6 @@ export function parse (
7574
platformIsPreTag = options.isPreTag || no
7675
platformMustUseProp = options.mustUseProp || no
7776
platformGetTagNamespace = options.getTagNamespace || no
78-
const isReservedTag = options.isReservedTag || no
79-
maybeComponent = (el: ASTElement) => !!el.component || !isReservedTag(el.tag)
8077

8178
transforms = pluckModuleFunction(options.modules, 'transformNode')
8279
preTransforms = pluckModuleFunction(options.modules, 'preTransformNode')
@@ -102,7 +99,7 @@ export function parse (
10299

103100
function closeElement (element) {
104101
if (!inVPre && !element.processed) {
105-
element = processElement(element, options)
102+
element = processElement(element, options, currentParent)
106103
}
107104
// tree management
108105
if (!stack.length && element !== root) {
@@ -156,7 +153,7 @@ export function parse (
156153
{ start: el.start }
157154
)
158155
}
159-
if (hasOwn(el.attrsMap, 'v-for')) {
156+
if (el.attrsMap.hasOwnProperty('v-for')) {
160157
warnOnce(
161158
'Cannot use v-for on stateful component root element because ' +
162159
'it renders multiple elements.',
@@ -380,7 +377,8 @@ function processRawAttrs (el) {
380377

381378
export function processElement (
382379
element: ASTElement,
383-
options: CompilerOptions
380+
options: CompilerOptions,
381+
parent: ASTElement | undefined
384382
) {
385383
processKey(element)
386384

@@ -393,7 +391,7 @@ export function processElement (
393391
)
394392

395393
processRef(element)
396-
processSlot(element)
394+
processSlot(element, parent)
397395
processComponent(element)
398396
for (let i = 0; i < transforms.length; i++) {
399397
element = transforms[i](element, options) || element
@@ -584,86 +582,19 @@ function processSlot (el) {
584582
)
585583
}
586584
el.slotScope = slotScope
587-
if (process.env.NODE_ENV !== 'production' && nodeHas$Slot(el)) {
588-
warn('Unepxected mixed usage of `slot-scope` and `$slot`.', el)
589-
}
590-
} else {
591-
// 2.6 $slot support
592-
// Context: https://github.com/vuejs/vue/issues/9180
593-
// Ideally, all slots should be compiled as functions (this is what we
594-
// are doing in 3.x), but for 2.x e want to preserve complete backwards
595-
// compatibility, and maintain the exact same compilation output for any
596-
// code that does not use the new syntax.
597-
598-
// recursively check component children for presence of `$slot` in all
599-
// expressions until running into a nested child component.
600-
if (maybeComponent(el) && childrenHas$Slot(el)) {
601-
processScopedSlots(el)
602-
}
603585
}
604586
const slotTarget = getBindingAttr(el, 'slot')
605587
if (slotTarget) {
606588
el.slotTarget = slotTarget === '""' ? '"default"' : slotTarget
607589
// preserve slot as an attribute for native shadow DOM compat
608590
// only for non-scoped slots.
609-
if (el.tag !== 'template' && !el.slotScope && !nodeHas$Slot(el)) {
591+
if (el.tag !== 'template' && !el.slotScope) {
610592
addAttr(el, 'slot', slotTarget, getRawBindingAttr(el, 'slot'))
611593
}
612594
}
613595
}
614596
}
615597

616-
function childrenHas$Slot (el): boolean {
617-
return el.children ? el.children.some(nodeHas$Slot) : false
618-
}
619-
620-
const $slotRE = /(^|[^\w_$])\$slot($|[^\w_$])/
621-
function nodeHas$Slot (node): boolean {
622-
// caching
623-
if (hasOwn(node, 'has$Slot')) {
624-
return (node.has$Slot: any)
625-
}
626-
if (node.type === 1) { // element
627-
for (const key in node.attrsMap) {
628-
if (dirRE.test(key) && $slotRE.test(node.attrsMap[key])) {
629-
return (node.has$Slot = true)
630-
}
631-
}
632-
return (node.has$Slot = childrenHas$Slot(node))
633-
} else if (node.type === 2) { // expression
634-
// TODO more robust logic for checking $slot usage
635-
return (node.has$Slot = $slotRE.test(node.expression))
636-
}
637-
return false
638-
}
639-
640-
function processScopedSlots (el) {
641-
// 1. group children by slot target
642-
const groups: any = {}
643-
for (let i = 0; i < el.children.length; i++) {
644-
const child = el.children[i]
645-
const target = child.slotTarget || '"default"'
646-
if (!groups[target]) {
647-
groups[target] = []
648-
}
649-
groups[target].push(child)
650-
}
651-
// 2. for each slot group, check if the group contains $slot
652-
for (const name in groups) {
653-
const group = groups[name]
654-
if (group.some(nodeHas$Slot)) {
655-
// 3. if a group contains $slot, all nodes in that group gets assigned
656-
// as a scoped slot to el and removed from children
657-
el.plain = false
658-
const slots = el.scopedSlots || (el.scopedSlots = {})
659-
const slotContainer = slots[name] = createASTElement('template', [], el)
660-
slotContainer.children = group
661-
slotContainer.slotScope = '$slot'
662-
el.children = el.children.filter(c => group.indexOf(c) === -1)
663-
}
664-
}
665-
}
666-
667598
function processComponent (el) {
668599
let binding
669600
if ((binding = getBindingAttr(el, 'is'))) {

test/unit/features/component/component-scoped-slot.spec.js

Lines changed: 0 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -631,92 +631,4 @@ describe('Component scoped slot', () => {
631631
expect(vm.$el.innerHTML).toBe('<p>hello</p>')
632632
}).then(done)
633633
})
634-
635-
// 2.6 $slot usage
636-
describe('$slot support', () => {
637-
it('should work', () => {
638-
const vm = new Vue({
639-
template: `<foo><div>{{$slot.foo}}</div></foo>`,
640-
components: { foo: { template: `<div><slot foo="hello"/></div>` }}
641-
}).$mount()
642-
expect(vm.$el.innerHTML).toBe(`<div>hello</div>`)
643-
})
644-
645-
it('should work for use of $slots in attributes', () => {
646-
const vm = new Vue({
647-
template: `<foo><div :id="$slot.foo"></div></foo>`,
648-
components: { foo: { template: `<div><slot foo="hello"/></div>` }}
649-
}).$mount()
650-
expect(vm.$el.innerHTML).toBe(`<div id="hello"></div>`)
651-
})
652-
653-
it('should work for root text nodes', () => {
654-
const vm = new Vue({
655-
template: `<foo>{{$slot.foo}}</foo>`,
656-
components: { foo: { template: `<div><slot foo="hello"/></div>` }}
657-
}).$mount()
658-
expect(vm.$el.innerHTML).toBe(`hello`)
659-
})
660-
661-
it('should work for mix of root text nodes and elements', () => {
662-
const vm = new Vue({
663-
template: `<foo>hi <div>{{ $slot.foo }}</div>{{$slot.foo}}</foo>`,
664-
components: { foo: { template: `<div><slot foo="hello"/></div>` }}
665-
}).$mount()
666-
expect(vm.$el.innerHTML).toBe(`hi <div>hello</div>hello`)
667-
})
668-
669-
it('should work for named slots', () => {
670-
const vm = new Vue({
671-
template: `<foo><div slot="foo">{{ $slot.foo }}</div></foo>`,
672-
components: { foo: { template: `<div><slot name="foo" foo="hello"/></div>` }}
673-
}).$mount()
674-
expect(vm.$el.innerHTML).toBe(`<div>hello</div>`)
675-
})
676-
677-
it('should work for mixed default and named slots', () => {
678-
const vm = new Vue({
679-
template: `<foo>{{ $slot.foo }}<div>{{ $slot.foo }}</div><div slot="foo">{{ $slot.foo }}</div></foo>`,
680-
components: { foo: { template: `<div><slot foo="default"/><slot name="foo" foo="foo"/></div>` }}
681-
}).$mount()
682-
expect(vm.$el.innerHTML).toBe(`default<div>default</div><div>foo</div>`)
683-
})
684-
685-
it('should work for mixed $slot and non-$slot slots', () => {
686-
const vm = new Vue({
687-
template: `<foo>{{ $slot.foo }}<div slot="foo">static</div><div>{{ $slot.foo }}</div></foo>`,
688-
components: { foo: { template: `<div><slot foo="default"/><slot name="foo"/></div>` }}
689-
}).$mount()
690-
expect(vm.$el.innerHTML).toBe(`default<div>default</div><div>static</div>`)
691-
})
692-
693-
// testing $slot detection: bracket access, using $slot alone, passing as arguments...
694-
it('should work for alternative $slot usage', () => {
695-
const vm = new Vue({
696-
template: `<foo>{{ $slot['foo'] }}<div slot="foo">{{ $slot }}</div><div>{{ pick($slot) }}</div></foo>`,
697-
methods: { pick: s => s.foo },
698-
components: { foo: { template: `<div><slot foo="default"/><slot name="foo"/></div>` }}
699-
}).$mount()
700-
expect(vm.$el.innerHTML).toBe(`default<div>default</div><div>{}</div>`)
701-
})
702-
703-
// should not consider detection if $slot is inside longer valid identifier
704-
it('should not break when template expression uses $slots', () => {
705-
const vm = new Vue({
706-
data: { some$slot: 123 },
707-
template: `<foo>{{ some$slot }}<div slot="foo">{{ $slots }}</div></foo>`,
708-
components: {
709-
foo: {
710-
render(h) {
711-
// should be compiled as normal slots
712-
expect(this.$slots.default).toBeTruthy()
713-
expect(this.$slots.foo).toBeTruthy()
714-
return h('div', [this.$slots.default, this.$slots.foo])
715-
}
716-
}
717-
}
718-
}).$mount()
719-
expect(vm.$el.innerHTML).toBe(`123<div>{}</div>`)
720-
})
721-
})
722634
})

0 commit comments

Comments
 (0)