Skip to content

Commit

Permalink
fix: support registered components in scopedSlots (#1065)
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyerburgh authored Dec 12, 2018
1 parent c69896a commit d4c118b
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 9 deletions.
5 changes: 3 additions & 2 deletions packages/create-instance/create-functional-component.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import createScopedSlots from './create-scoped-slots'

export default function createFunctionalComponent (
component: Component,
mountingOptions: Options
mountingOptions: Options,
_Vue: Component
): Component {
if (mountingOptions.context && typeof mountingOptions.context !== 'object') {
throwError('mount.context must be an object')
Expand All @@ -29,7 +30,7 @@ export default function createFunctionalComponent (
})
}

context.scopedSlots = createScopedSlots(mountingOptions.scopedSlots)
context.scopedSlots = createScopedSlots(mountingOptions.scopedSlots, _Vue)

return {
render (h: Function) {
Expand Down
4 changes: 2 additions & 2 deletions packages/create-instance/create-instance.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default function createInstance (
(component.options && component.options.functional) ||
component.functional
) {
component = createFunctionalComponent(component, options)
component = createFunctionalComponent(component, options, _Vue)
} else if (options.context) {
throwError(
`mount.context can only be used when mounting a ` +
Expand Down Expand Up @@ -116,7 +116,7 @@ export default function createInstance (
options.provide = () => obj
}

const scopedSlots = createScopedSlots(options.scopedSlots)
const scopedSlots = createScopedSlots(options.scopedSlots, _Vue)

if (options.parentComponent && !isPlainObject(options.parentComponent)) {
throwError(
Expand Down
13 changes: 8 additions & 5 deletions packages/create-instance/create-scoped-slots.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
// @flow

import Vue from 'vue'
import { compileToFunctions } from 'vue-template-compiler'
import { throwError, vueVersion } from 'shared/util'

function isDestructuringSlotScope (slotScope: string): boolean {
return slotScope[0] === '{' && slotScope[slotScope.length - 1] === '}'
}

function getVueTemplateCompilerHelpers (): { [name: string]: Function } {
const vue = new Vue()
function getVueTemplateCompilerHelpers (
_Vue: Component
): { [name: string]: Function } {
// $FlowIgnore
const vue = new _Vue()
const helpers = {}
const names = [
'_c',
Expand Down Expand Up @@ -52,7 +54,8 @@ function customWarn (msg) {
}

export default function createScopedSlots (
scopedSlotsOption: ?{ [slotName: string]: string | Function }
scopedSlotsOption: ?{ [slotName: string]: string | Function },
_Vue: Component
): {
[slotName: string]: (props: Object) => VNode | Array<VNode>
} {
Expand All @@ -61,7 +64,7 @@ export default function createScopedSlots (
return scopedSlots
}
validateEnvironment()
const helpers = getVueTemplateCompilerHelpers()
const helpers = getVueTemplateCompilerHelpers(_Vue)
for (const scopedSlotName in scopedSlotsOption) {
const slot = scopedSlotsOption[scopedSlotName]
const isFn = typeof slot === 'function'
Expand Down
25 changes: 25 additions & 0 deletions test/specs/mounting-options/scopedSlots.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
describeWithShallowAndMount,
vueVersion
} from '~resources/utils'
import { createLocalVue } from '~vue/test-utils'
import ComponentWithScopedSlots from '~resources/components/component-with-scoped-slots.vue'
import { itDoNotRunIf } from 'conditional-specs'

Expand Down Expand Up @@ -234,4 +235,28 @@ describeWithShallowAndMount('scopedSlots', mountingMethod => {
.with.property('message', message)
}
)

itDoNotRunIf(
vueVersion < 2.5 || mountingMethod.name !== 'mount',
'renders using localVue constructor',
() => {
const RegisteredComponent = {
render: h => h('span')
}
const TestComponent = {
template: '<div><slot name="single" /></div>'
}

const localVue = createLocalVue()
localVue.component('registered-component', RegisteredComponent)

const wrapper = mountingMethod(TestComponent, {
scopedSlots: {
single: '<template><registered-component /></template>'
},
localVue
})

expect(wrapper.html()).to.contain('span')
})
})

0 comments on commit d4c118b

Please sign in to comment.