fix(ssr): respect render function from extends/mixins in ssr (#3006)

fix #3004
This commit is contained in:
HcySunYang 2021-03-25 22:32:17 +08:00 committed by GitHub
parent 7fad69c260
commit 0a583d5ca2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 53 additions and 7 deletions

View File

@ -670,9 +670,13 @@ function finishComponentSetup(
// template / render function normalization // template / render function normalization
if (__NODE_JS__ && isSSR) { if (__NODE_JS__ && isSSR) {
if (Component.render) { // 1. the render function may already exist, returned by `setup`
instance.render = Component.render as InternalRenderFunction // 2. otherwise try to use the `Component.render`
} // 3. if the component doesn't have a render function,
// set `instance.render` to NOOP so that it can inherit the render function from mixins/extend
instance.render = (instance.render ||
Component.render ||
NOOP) as InternalRenderFunction
} else if (!instance.render) { } else if (!instance.render) {
// could be set from setup() // could be set from setup()
if (compile && Component.template && !Component.render) { if (compile && Component.template && !Component.render) {
@ -711,7 +715,8 @@ function finishComponentSetup(
} }
// warn missing template/render // warn missing template/render
if (__DEV__ && !Component.render && instance.render === NOOP) { // the runtime compilation of template in SSR is done by server-render
if (__DEV__ && !Component.render && instance.render === NOOP && !isSSR) {
/* istanbul ignore if */ /* istanbul ignore if */
if (!compile && Component.template) { if (!compile && Component.template) {
warn( warn(

View File

@ -99,6 +99,46 @@ function testRender(type: string, render: typeof renderToString) {
).toBe(`<div>hello</div>`) ).toBe(`<div>hello</div>`)
}) })
test('components using defineComponent with extends option', async () => {
expect(
await render(
createApp(
defineComponent({
extends: {
data() {
return { msg: 'hello' }
},
render(this: any) {
return h('div', this.msg)
}
}
})
)
)
).toBe(`<div>hello</div>`)
})
test('components using defineComponent with mixins option', async () => {
expect(
await render(
createApp(
defineComponent({
mixins: [
{
data() {
return { msg: 'hello' }
},
render(this: any) {
return h('div', this.msg)
}
}
]
})
)
)
).toBe(`<div>hello</div>`)
})
test('optimized components', async () => { test('optimized components', async () => {
expect( expect(
await render( await render(

View File

@ -22,7 +22,8 @@ import {
isString, isString,
isVoidTag, isVoidTag,
ShapeFlags, ShapeFlags,
isArray isArray,
NOOP
} from '@vue/shared' } from '@vue/shared'
import { ssrRenderAttrs } from './helpers/ssrRenderAttrs' import { ssrRenderAttrs } from './helpers/ssrRenderAttrs'
import { ssrCompile } from './helpers/ssrCompile' import { ssrCompile } from './helpers/ssrCompile'
@ -118,7 +119,7 @@ function renderComponentSubTree(
) )
} else { } else {
if ( if (
!instance.render && (!instance.render || instance.render === NOOP) &&
!instance.ssrRender && !instance.ssrRender &&
!comp.ssrRender && !comp.ssrRender &&
isString(comp.template) isString(comp.template)
@ -155,7 +156,7 @@ function renderComponentSubTree(
instance.ctx instance.ctx
) )
setCurrentRenderingInstance(null) setCurrentRenderingInstance(null)
} else if (instance.render) { } else if (instance.render && instance.render !== NOOP) {
renderVNode( renderVNode(
push, push,
(instance.subTree = renderComponentRoot(instance)), (instance.subTree = renderComponentRoot(instance)),