Skip to content

Commit 354d79c

Browse files
committed
fix(runtime-core): respect render function from mixins
fix #1630
1 parent 71c3c6e commit 354d79c

File tree

3 files changed

+40
-21
lines changed

3 files changed

+40
-21
lines changed

packages/runtime-core/__tests__/apiOptions.spec.ts

+11
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,17 @@ describe('api: options', () => {
520520
])
521521
})
522522

523+
test('render from mixin', () => {
524+
const Comp = {
525+
mixins: [
526+
{
527+
render: () => 'from mixin'
528+
}
529+
]
530+
}
531+
expect(renderToString(h(Comp))).toBe('from mixin')
532+
})
533+
523534
test('extends', () => {
524535
const calls: string[] = []
525536
const Base = {

packages/runtime-core/src/component.ts

+21-19
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,7 @@ function finishComponentSetup(
589589
instance.render = Component.render as InternalRenderFunction
590590
}
591591
} else if (!instance.render) {
592+
// could be set from setup()
592593
if (compile && Component.template && !Component.render) {
593594
if (__DEV__) {
594595
startMeasure(instance, `compile`)
@@ -604,25 +605,6 @@ function finishComponentSetup(
604605
;(Component.render as InternalRenderFunction)._rc = true
605606
}
606607

607-
if (__DEV__ && !Component.render) {
608-
/* istanbul ignore if */
609-
if (!compile && Component.template) {
610-
warn(
611-
`Component provided template option but ` +
612-
`runtime compilation is not supported in this build of Vue.` +
613-
(__ESM_BUNDLER__
614-
? ` Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".`
615-
: __ESM_BROWSER__
616-
? ` Use "vue.esm-browser.js" instead.`
617-
: __GLOBAL__
618-
? ` Use "vue.global.js" instead.`
619-
: ``) /* should not happen */
620-
)
621-
} else {
622-
warn(`Component is missing template or render function.`)
623-
}
624-
}
625-
626608
instance.render = (Component.render || NOOP) as InternalRenderFunction
627609

628610
// for runtime-compiled render functions using `with` blocks, the render
@@ -642,6 +624,26 @@ function finishComponentSetup(
642624
applyOptions(instance, Component)
643625
currentInstance = null
644626
}
627+
628+
// warn missing template/render
629+
if (__DEV__ && !Component.render && instance.render === NOOP) {
630+
/* istanbul ignore if */
631+
if (!compile && Component.template) {
632+
warn(
633+
`Component provided template option but ` +
634+
`runtime compilation is not supported in this build of Vue.` +
635+
(__ESM_BUNDLER__
636+
? ` Configure your bundler to alias "vue" to "vue/dist/vue.esm-bundler.js".`
637+
: __ESM_BROWSER__
638+
? ` Use "vue.esm-browser.js" instead.`
639+
: __GLOBAL__
640+
? ` Use "vue.global.js" instead.`
641+
: ``) /* should not happen */
642+
)
643+
} else {
644+
warn(`Component is missing template or render function.`)
645+
}
646+
}
645647
}
646648

647649
const attrHandlers: ProxyHandler<Data> = {

packages/runtime-core/src/componentOptions.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
SetupContext,
55
ComponentInternalOptions,
66
PublicAPIComponent,
7-
Component
7+
Component,
8+
InternalRenderFunction
89
} from './component'
910
import {
1011
isFunction,
@@ -390,6 +391,7 @@ export function applyOptions(
390391
deactivated,
391392
beforeUnmount,
392393
unmounted,
394+
render,
393395
renderTracked,
394396
renderTriggered,
395397
errorCaptured
@@ -398,14 +400,18 @@ export function applyOptions(
398400
const publicThis = instance.proxy!
399401
const ctx = instance.ctx
400402
const globalMixins = instance.appContext.mixins
401-
// call it only during dev
403+
404+
if (asMixin && render && instance.render === NOOP) {
405+
instance.render = render as InternalRenderFunction
406+
}
402407

403408
// applyOptions is called non-as-mixin once per instance
404409
if (!asMixin) {
405410
callSyncHook('beforeCreate', options, publicThis, globalMixins)
406411
// global mixins are applied first
407412
applyMixins(instance, globalMixins, deferredData, deferredWatch)
408413
}
414+
409415
// extending a base component...
410416
if (extendsOptions) {
411417
applyOptions(instance, extendsOptions, deferredData, deferredWatch, true)

0 commit comments

Comments
 (0)