Skip to content

Commit 5b1b094

Browse files
authored
fix(SSR): value set for props, fix #550 (#551)
1 parent e44311f commit 5b1b094

File tree

2 files changed

+62
-4
lines changed

2 files changed

+62
-4
lines changed

src/reactivity/reactive.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { AnyObject } from '../types/basic'
22
import { getRegisteredVueOrDefault } from '../runtimeContext'
3-
import { isPlainObject, def, warn, isArray, hasOwn } from '../utils'
3+
import { isPlainObject, def, warn, isArray, hasOwn, noopFn } from '../utils'
44
import { isComponentInstance, defineComponentInstance } from '../utils/helper'
55
import { RefKey } from '../utils/symbols'
66
import { isRef, UnwrapRef } from './ref'
@@ -113,14 +113,26 @@ function observe<T>(obj: T): T {
113113

114114
// in SSR, there is no __ob__. Mock for reactivity check
115115
if (!hasOwn(observed, '__ob__')) {
116-
def(observed, '__ob__', {})
116+
def(observed, '__ob__', mockObserver(observed))
117117
}
118118

119119
return observed
120120
}
121121

122122
export function createObserver() {
123-
return observe<any>({}).__ob__ || {}
123+
return observe<any>({}).__ob__
124+
}
125+
126+
function mockObserver(value: any = {}): any {
127+
return {
128+
value,
129+
dep: {
130+
notify: noopFn,
131+
depend: noopFn,
132+
addSub: noopFn,
133+
removeSub: noopFn,
134+
},
135+
}
124136
}
125137

126138
export function shallowReactive<T extends object = any>(obj: T): T

test/ssr/ssrReactive.spec.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,15 @@
33
*/
44

55
import Vue from '../vue'
6-
import { isReactive, reactive, ref, isRaw, isRef, shallowRef } from '../../src'
6+
import {
7+
isReactive,
8+
reactive,
9+
ref,
10+
isRaw,
11+
isRef,
12+
set,
13+
shallowRef,
14+
} from '../../src'
715
import { createRenderer } from 'vue-server-renderer'
816

917
describe('SSR Reactive', () => {
@@ -44,4 +52,42 @@ describe('SSR Reactive', () => {
4452
expect(isRef(state)).toBe(true)
4553
expect(isRaw(state)).toBe(false)
4654
})
55+
56+
// #550
57+
it('props should work with set', async (done) => {
58+
let props: any
59+
60+
const app = new Vue({
61+
render(this: any, h) {
62+
return h('child', { attrs: { msg: this.msg } })
63+
},
64+
setup() {
65+
return { msg: ref('hello') }
66+
},
67+
components: {
68+
child: {
69+
render(this: any, h: any) {
70+
return h('span', this.data.msg)
71+
},
72+
props: ['msg'],
73+
setup(_props) {
74+
props = _props
75+
76+
return { data: _props }
77+
},
78+
},
79+
},
80+
})
81+
82+
const serverRenderer = createRenderer()
83+
const html = await serverRenderer.renderToString(app)
84+
85+
expect(html).toBe('<span data-server-rendered="true">hello</span>')
86+
87+
expect(props.bar).toBeUndefined()
88+
set(props, 'bar', 'bar')
89+
expect(props.bar).toBe('bar')
90+
91+
done()
92+
})
4793
})

0 commit comments

Comments
 (0)