8000 simplify slot resolution - re-enable dynamic slot names · MicroTransactionsMatterToo/vue@bed322e · GitHub
[go: up one dir, main page]

Skip to content

Commit bed322e

Browse files
committed
simplify slot resolution - re-enable dynamic slot names
1 parent 72c83e3 commit bed322e

File tree

6 files changed

+84
-120
lines changed

6 files changed

+84
-120
lines changed

src/compiler/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export * from './compile'
22
export * from './transclude'
3-
export * from './scan-slots'
3+
export * from './resolve-slots'

src/compiler/resolve-slots.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { parseTemplate } from '../parsers/template'
2+
import {
3+
isTemplate,
4+
toArray
5+
} from '../util/index'
6+
7+
/**
8+
* Scan and determine slot content distribution.
9+
* We do this during transclusion instead at compile time so that
10+
* the distribution is decoupled from the compilation order of
11+
* the slots.
12+
*
13+
* @param {Element|DocumentFragment} template
14+
* @param {Element} content
15+
* @param {Vue} vm
16+
*/
17+
18+
export function resolveSlots (vm, content) {
19+
if (!content) {
20+
return
21+
}
22+
var contents = vm._slotContents = Object.create(null)
23+
var el, name
24+
for (var i = 0, l = content.children.length; i < l; i++) {
25+
el = content.children[i]
26+
/* eslint-disable no-cond-assign */
27+
if (name = el.getAttribute('slot')) {
28+
(contents[name] || (contents[name] = [])).push(el)
29+
}
30+
/* eslint-enable no-cond-assign */
31+
}
32+
for (name in contents) {
33+
contents[name] = extractFragment(contents[name], content)
34+
}
35+
if (content.hasChildNodes()) {
36+
contents['default'] = extractFragment(content.childNodes, content)
37+
}
38+
}
39+
40+
/**
41+
* Extract qualified content nodes from a node list.
42+
*
43+
* @param {NodeList} nodes
44+
* @return {DocumentFragment}
45+
*/
46+
47+
function extractFragment (nodes, parent) {
48+
var frag = document.createDocumentFragment()
49+
nodes = toArray(nodes)
50+
for (var i = 0, l = nodes.length; i < l; i++) {
51+
var node = nodes[i]
52+
if (
53+
isTemplate(node) &&
54+
!node.hasAttribute('v-if') &&
55+
!node.hasAttribute('v-for')
56+
) {
57+
parent.removeChild(node)
58+
node = parseTemplate(node)
59+
}
60+
frag.appendChild(node)
61+
}
62+
return frag
63+
}

src/compiler/scan-slots.js

Lines changed: 0 additions & 107 deletions
This file was deleted.

src/instance/internal/lifecycle.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
compile,
1111
compileRoot,
1212
transclude,
13-
scanSlots
13+
resolveSlots
1414
} from '../../compiler/index'
1515

1616
export default function (Vue) {
@@ -68,9 +68,8 @@ export default function (Vue) {
6868
var contextOptions = this._context && this._context.$options
6969
var rootLinker = compileRoot(el, options, contextOptions)
7070

71-
// scan for slot distribution before compiling the content
72-
// so that it's decoupeld from slot/directive compilation order
73-
scanSlots(el, options._content, this)
71+
// resolve slot distribution
72+
resolveSlots(this, options._content)
7473

7574
// compile and link the rest
7675
var contentLinkFn

src/util/env.js

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,6 @@ export const inBrowser =
88
typeof window !== 'undefined' &&
99
Object.prototype.toString.call(window) !== '[object Object]'
1010

11-
// Check if the browser supports native <template>.
12-
export const hasNativeTemplate = (function () {
13-
var t = document.createElement('template')
14-
return t.content && t.content.nodeType === 11
15-
})()
16-
1711
// detect devtools
1812
export const devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__
1913

test/unit/specs/directives/element/slot_spec.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,14 +132,14 @@ describe('Slot Distribution', function () {
132132
expect(el.lastChild.textContent).toBe('fallback c')
133133
})
134134

135-
it('should warn expressions in slot names', function () {
135+
it('should accept expressions in selectors', function () {
136136
el.innerHTML = '<p>one</p><p slot="two">two</p>'
137137
options.template = '<slot :name="theName"></slot>'
138138
options.data = {
139139
theName: 'two'
140140
}
141141
mount()
142-
expect('slot names cannot be dynamic').toHaveBeenWarned()
142+
expect(el.innerHTML).toBe('<p slot="two">two</p>')
143143
})
144144

145145
it('content should be dynamic and compiled in parent scope', function (done) {
@@ -196,6 +196,21 @@ describe('Slot Distribution', function () {
196196
})
197197
})
198198

199+
it('inline v-for', function () {
200+
el.innerHTML = '<p slot="1">1</p><p slot="2">2</p><p slot="3">3</p>'
201+
new Vue({
202+
el: el,
203+
template: '<div v-for="n in list"><slot :name="$index + 1"></slot></div>',
204+
data: {
205+
list: 0
206+
},
207+
beforeCompile: function () {
208+
this.list = this.$options._content.querySelectorAll('p').length
209+
}
210+
})
211+
expect(el.innerHTML).toBe('<div><p slot="1">1</p></div><div><p slot="2">2</p></div><div><p slot="3">3</p></div>')
212+
})
213+
199214
it('v-for + component + parent directive + transclusion', function (done) {
200215
var vm = new Vue({
201216
el: el,

0 commit comments

Comments
 (0)
0