Skip to content

Commit 9b22d86

Browse files
committed
fix: install ssr helpers for functional context during SSR
close #7443, ref nuxt/nuxt#2565
1 parent 3d431a5 commit 9b22d86

File tree

6 files changed

+55
-21
lines changed

6 files changed

+55
-21
lines changed

flow/component.js

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ declare interface Component {
1616
static directive: (id: string, def?: Function | Object) => Function | Object | void;
1717
static component: (id: string, def?: Class<Component> | Object) => Class<Component>;
1818
static filter: (id: string, def?: Function) => Function | void;
19+
// functional context constructor
20+
static FunctionalRenderContext: Function;
1921

2022
// public properties
2123
$el: any; // so that we can attach __vue__ to it

scripts/config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ const builds = {
123123
format: 'cjs',
124124
external: Object.keys(require('../packages/vue-server-renderer/package.json').dependencies)
125125
},
126-
'web-server-basic-renderer': {
126+
'web-server-renderer-basic': {
127127
entry: resolve('web/entry-server-basic-renderer.js'),
128128
dest: resolve('packages/vue-server-renderer/basic.js'),
129129
format: 'umd',

src/core/index.js

+6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Vue from './instance/index'
22
import { initGlobalAPI } from './global-api/index'
33
import { isServerRendering } from 'core/util/env'
4+
import { FunctionalRenderContext } from 'core/vdom/create-functional-component'
45

56
initGlobalAPI(Vue)
67

@@ -15,6 +16,11 @@ Object.defineProperty(Vue.prototype, '$ssrContext', {
1516
}
1617
})
1718

19+
// expose FunctionalRenderContext for ssr runtime helper installation
20+
Object.defineProperty(Vue, 'FunctionalRenderContext', {
21+
value: FunctionalRenderContext
22+
})
23+
1824
Vue.version = '__VERSION__'
1925

2026
export default Vue

src/core/vdom/create-functional-component.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ import {
1515
validateProp
1616
} from '../util/index'
1717

18-
function FunctionalRenderContext (
19-
data,
20-
props,
21-
children,
22-
parent,
23-
Ctor
18+
export function FunctionalRenderContext (
19+
data: VNodeData,
20+
props: Object,
21+
children: ?Array<VNode>,
22+
parent: Component,
23+
Ctor: Class<Component>
2424
) {
2525
const options = Ctor.options
2626
this.data = data

src/server/optimizing-compiler/runtime-helpers.js

+21-14
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,29 @@ import {
1717
isRenderableAttr
1818
} from 'web/server/util'
1919

20+
const ssrHelpers = {
21+
_ssrEscape: escape,
22+
_ssrNode: renderStringNode,
23+
_ssrList: renderStringList,
24+
_ssrAttr: renderAttr,
25+
_ssrAttrs: renderAttrs,
26+
_ssrDOMProps: renderDOMProps,
27+
_ssrClass: renderSSRClass,
28+
_ssrStyle: renderSSRStyle
29+
}
30+
2031
export function installSSRHelpers (vm: Component) {
21-
if (vm._ssrNode) return
22-
let Ctor = vm.constructor
23-
while (Ctor.super) {
24-
Ctor = Ctor.super
32+
if (vm._ssrNode) {
33+
return
34+
}
35+
let Vue = vm.constructor
36+
while (Vue.super) {
37+
Vue = Vue.super
38+
}
39+
extend(Vue.prototype, ssrHelpers)
40+
if (Vue.FunctionalRenderContext) {
41+
extend(Vue.FunctionalRenderContext.prototype, ssrHelpers)
2542
}
26-
extend(Ctor.prototype, {
27-
_ssrEscape: escape,
28-
_ssrNode: renderStringNode,
29-
_ssrList: renderStringList,
30-
_ssrAttr: renderAttr,
31-
_ssrAttrs: renderAttrs,
32-
_ssrDOMProps: renderDOMProps,
33-
_ssrClass: renderSSRClass,
34-
_ssrStyle: renderSSRStyle
35-
})
3643
}
3744

3845
class StringNode {

test/ssr/ssr-string.spec.js

+19
Original file line numberDiff line numberDiff line change
@@ -1145,6 +1145,25 @@ describe('SSR: renderToString', () => {
11451145
done()
11461146
})
11471147
})
1148+
1149+
it('should expose ssr helpers on functional context', done => {
1150+
let called = false
1151+
renderVmWithOptions({
1152+
template: `<div><foo/></div>`,
1153+
components: {
1154+
foo: {
1155+
functional: true,
1156+
render (h, ctx) {
1157+
expect(ctx._ssrNode).toBeTruthy()
1158+
called = true
1159+
}
1160+
}
1161+
}
1162+
}, () => {
1163+
expect(called).toBe(true)
1164+
done()
1165+
})
1166+
})
11481167
})
11491168

11501169
function renderVmWithOptions (options, cb) {

0 commit comments

Comments
 (0)