Skip to content

Commit ccd11fb

Browse files
committed
extract slots from template content (fix #2435)
1 parent ba82b76 commit ccd11fb

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

src/compiler/scan-slots.js

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import {
33
isTemplate,
44
toArray,
55
getBindAttr,
6-
warn
6+
warn,
7+
hasNativeTemplate
78
} from '../util/index'
89

910
/**
@@ -22,7 +23,7 @@ export function scanSlots (template, content, vm) {
2223
return
2324
}
2425
var contents = vm._slotContents = {}
25-
var slots = template.querySelectorAll('slot')
26+
var slots = findSlots(template)
2627
if (slots.length) {
2728
var hasDefault, slot, name
2829
for (var i = 0, l = slots.length; i < l; i++) {
@@ -56,6 +57,27 @@ export function scanSlots (template, content, vm) {
5657
}
5758
}
5859

60+
/**
61+
* Find all slots in a template, including those nested under
62+
* a <template> element's content node.
63+
*
64+
* @param {Element} el
65+
* @return {Array|NodeList}
66+
*/
67+
68+
function findSlots (el) {
69+
var slots = el.querySelectorAll('slot')
70+
/* istanbul ignore if */
71+
if (hasNativeTemplate) {
72+
slots = toArray(slots)
73+
var templates = el.querySelectorAll('template')
74+
for (var i = 0; i < templates.length; i++) {
75+
slots.push.apply(slots, findSlots(templates[i].content))
76+
}
77+
}
78+
return slots
79+
}
80+
5981
/**
6082
* Extract qualified content nodes from a node list.
6183
*

src/util/env.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ 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+
1117
// detect devtools
1218
export const devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__
1319

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,4 +406,28 @@ describe('Slot Distribution', function () {
406406
done()
407407
})
408408
})
409+
410+
// #2435
411+
it('slot inside template', function () {
412+
var vm = new Vue({
413+
el: el,
414+
template: '<test>hi</test>',
415+
components: {
416+
test: {
417+
data: function () {
418+
return { ok: true }
419+
},
420+
template:
421+
'<div>' +
422+
'<template v-if="ok">' +
423+
'<template v-if="ok">' +
424+
'<slot>{{ msg }}</slot>' +
425+
'</template>' +
426+
'</template>' +
427+
'</div>'
428+
}
429+
}
430+
})
431+
expect(vm.$el.textContent).toBe('hi')
432+
})
409433
})

0 commit comments

Comments
 (0)