Skip to content

Commit 0a583d5

Browse files
authored
fix(ssr): respect render function from extends/mixins in ssr (#3006)
fix #3004
1 parent 7fad69c commit 0a583d5

File tree

3 files changed

+53
-7
lines changed

3 files changed

+53
-7
lines changed

packages/runtime-core/src/component.ts

+9-4
Original file line numberDiff line numberDiff line change
@@ -670,9 +670,13 @@ function finishComponentSetup(
670670

671671
// template / render function normalization
672672
if (__NODE_JS__ && isSSR) {
673-
if (Component.render) {
674-
instance.render = Component.render as InternalRenderFunction
675-
}
673+
// 1. the render function may already exist, returned by `setup`
674+
// 2. otherwise try to use the `Component.render`
675+
// 3. if the component doesn't have a render function,
676+
// set `instance.render` to NOOP so that it can inherit the render function from mixins/extend
677+
instance.render = (instance.render ||
678+
Component.render ||
679+
NOOP) as InternalRenderFunction
676680
} else if (!instance.render) {
677681
// could be set from setup()
678682
if (compile && Component.template && !Component.render) {
@@ -711,7 +715,8 @@ function finishComponentSetup(
711715
}
712716

713717
// warn missing template/render
714-
if (__DEV__ && !Component.render && instance.render === NOOP) {
718+
// the runtime compilation of template in SSR is done by server-render
719+
if (__DEV__ && !Component.render && instance.render === NOOP && !isSSR) {
715720
/* istanbul ignore if */
716721
if (!compile && Component.template) {
717722
warn(

packages/server-renderer/__tests__/render.spec.ts

+40
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,46 @@ function testRender(type: string, render: typeof renderToString) {
9999
).toBe(`<div>hello</div>`)
100100
})
101101

102+
test('components using defineComponent with extends option', async () => {
103+
expect(
104+
await render(
105+
createApp(
106+
defineComponent({
107+
extends: {
108+
data() {
109+
return { msg: 'hello' }
110+
},
111+
render(this: any) {
112+
return h('div', this.msg)
113+
}
114+
}
115+
})
116+
)
117+
)
118+
).toBe(`<div>hello</div>`)
119+
})
120+
121+
test('components using defineComponent with mixins option', async () => {
122+
expect(
123+
await render(
124+
createApp(
125+
defineComponent({
126+
mixins: [
127+
{
128+
data() {
129+
return { msg: 'hello' }
130+
},
131+
render(this: any) {
132+
return h('div', this.msg)
133+
}
134+
}
135+
]
136+
})
137+
)
138+
)
139+
).toBe(`<div>hello</div>`)
140+
})
141+
102142
test('optimized components', async () => {
103143
expect(
104144
await render(

packages/server-renderer/src/render.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ import {
2222
isString,
2323
isVoidTag,
2424
ShapeFlags,
25-
isArray
25+
isArray,
26+
NOOP
2627
} from '@vue/shared'
2728
import { ssrRenderAttrs } from './helpers/ssrRenderAttrs'
2829
import { ssrCompile } from './helpers/ssrCompile'
@@ -118,7 +119,7 @@ function renderComponentSubTree(
118119
)
119120
} else {
120121
if (
121-
!instance.render &&
122+
(!instance.render || instance.render === NOOP) &&
122123
!instance.ssrRender &&
123124
!comp.ssrRender &&
124125
isString(comp.template)
@@ -155,7 +156,7 @@ function renderComponentSubTree(
155156
instance.ctx
156157
)
157158
setCurrentRenderingInstance(null)
158-
} else if (instance.render) {
159+
} else if (instance.render && instance.render !== NOOP) {
159160
renderVNode(
160161
push,
161162
(instance.subTree = renderComponentRoot(instance)),

0 commit comments

Comments
 (0)