Skip to content

Commit

Permalink
feat: resolve a template tag of an injected named slot (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
ktsn committed Jul 4, 2018
1 parent 4f274fc commit 2102711
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 2 deletions.
26 changes: 24 additions & 2 deletions src/view/components/Child.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import Expression from './Expression.vue'
import { ElementChild } from '@/parser/template/types'
import { DefaultValue, ChildComponent } from '@/parser/script/types'
export default Vue.extend({
// Assign to a constant to recursively use this component
const Child = Vue.extend({
name: 'Child',
functional: true,
Expand Down Expand Up @@ -42,10 +43,30 @@ export default Vue.extend({
switch (data.type) {
case 'Element':
const slot = data.startTag.attributes.find(attr => attr.name === 'slot')
const slotName = slot && slot.value
// Replace AST <template> with actual <template> element
// to handle named slot in Vue.js correctly.
if (slotName && data.name === 'template') {
return h(
'template',
{ slot: slotName },
data.children.map(child => {
return h(Child, {
props: {
...props,
data: child
},
on: listeners
})
})
)
}
return h(data.name === 'slot' ? NodeSlot : ContainerNode, {
props,
on: listeners,
slot: slot && slot.value
slot: slotName
})
case 'TextNode':
return [data.text]
Expand All @@ -61,4 +82,5 @@ export default Vue.extend({
}
}
})
export default Child
</script>
2 changes: 2 additions & 0 deletions test/view/VueComponent/__snapshots__/slot.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ exports[`VueComponent slot renders named slot content 1`] = `"<div><style></styl
exports[`VueComponent slot renders placeholder slot content 1`] = `"<div><style></style><div class=\\"\\"><p class=\\"\\">placeholder content</p></div></div>"`;
exports[`VueComponent slot renders slot content 1`] = `"<div><style></style><div class=\\"\\"><style></style><div data-scope-scope-id=\\"\\" class=\\"\\"><p data-scope-scope-id=\\"\\" class=\\"\\">foo content</p><p class=\\"\\">injected</p></div></div></div>"`;
exports[`VueComponent slot resolves template element children as the named slot 1`] = `"<div><style></style><div class=\\"\\"><style></style><div data-scope-scope-id=\\"\\" class=\\"\\"><strong class=\\"\\">named</strong><span class=\\"\\">content</span></div></div></div>"`;
38 changes: 38 additions & 0 deletions test/view/VueComponent/slot.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,42 @@ describe('VueComponent slot', () => {

expect(wrapper.html()).toMatchSnapshot()
})

it('resolves template element children as the named slot', () => {
// prettier-ignore
const template = createTemplate([
h('Foo', [], [
h('template', [a('slot', 'test')], [
h('strong', [], ['named']),
h('span', [], ['content'])
])
])
])

const components = {
'file://Foo.vue': {
// prettier-ignore
template: createTemplate([
h('div', [], [
h('slot', [a('name', 'test')], [])
])
])
}
}

const wrapper = render(
template,
[],
[],
[
{
name: 'Foo',
uri: 'file://Foo.vue'
}
],
components
)

expect(wrapper.html()).toMatchSnapshot()
})
})

0 comments on commit 2102711

Please sign in to comment.