File tree 3 files changed +55
-2
lines changed 3 files changed +55
-2
lines changed Original file line number Diff line number Diff line change @@ -2,7 +2,8 @@ import { VueConstructor } from 'vue';
2
2
import { Context } from './types/vue' ;
3
3
import { isWrapper } from './helper' ;
4
4
import { setCurrentVM } from './runtimeContext' ;
5
- import { isPlainObject , assert , proxy } from './utils' ;
5
+ import { isPlainObject , assert , proxy , isFunction } from './utils' ;
6
+ import { value } from './functions/state' ;
6
7
7
8
export function mixin ( Vue : VueConstructor ) {
8
9
Vue . mixin ( {
@@ -56,7 +57,14 @@ export function mixin(Vue: VueConstructor) {
56
57
}
57
58
58
59
Object . keys ( binding ) . forEach ( name => {
59
- const bindingValue = binding [ name ] ;
60
+ let bindingValue = binding [ name ] ;
61
+ if ( bindingValue === undefined )
62
+ return ;
63
+ // make plain value reactive
64
+ if ( ! isWrapper ( bindingValue ) && ! isFunction ( bindingValue ) && ! Object . isFrozen ( bindingValue ) ) {
65
+ bindingValue = value ( bindingValue ) ;
66
+ }
67
+ // bind to vm
60
68
if ( isWrapper ( bindingValue ) ) {
61
69
bindingValue . setVmProperty ( vm , name ) ;
62
70
} else {
Original file line number Diff line number Diff line change @@ -33,3 +33,7 @@ export function isArray<T>(x: unknown): x is T[] {
33
33
export function isPlainObject < T extends Object = { } > ( x : unknown ) : x is T {
34
34
return toString ( x ) === '[object Object]' ;
35
35
}
36
+
37
+ export function isFunction ( x : unknown ) : x is Function {
38
+ return typeof x === 'function' ;
39
+ }
Original file line number Diff line number Diff line change @@ -236,4 +236,45 @@ describe('setup', () => {
236
236
} ,
237
237
} ) . $mount ( ) ;
238
238
} ) ;
239
+
240
+ it ( 'should make returned plain value reactive (value)' , done => {
241
+ const vm = new Vue ( {
242
+ setup ( ) {
243
+ return {
244
+ name : null ,
245
+ nested : {
246
+ object : {
247
+ msg : 'foo'
248
+ }
249
+ } ,
250
+ } ;
251
+ } ,
252
+ template : '<div>{{ name }}, {{ nested.object.msg }}</div>' ,
253
+ } ) . $mount ( ) ;
254
+ expect ( vm . $el . textContent ) . toBe ( ', foo' ) ;
255
+ vm . name = 'foo' ;
256
+ vm . nested . object . msg = 'bar' ;
257
+ waitForUpdate ( ( ) => {
258
+ expect ( vm . $el . textContent ) . toBe ( 'foo, bar' ) ;
259
+ } ) . then ( done ) ;
260
+ } )
261
+
262
+ it ( 'should make returned plain value reactive (object)' , done => {
263
+ const vm = new Vue ( {
264
+ setup ( ) {
265
+ return {
266
+ form : {
267
+ a : 1 ,
268
+ b : 2
269
+ }
270
+ } ;
271
+ } ,
272
+ template : '<div>{{ form.a }}, {{ form.b }}</div>' ,
273
+ } ) . $mount ( ) ;
274
+ expect ( vm . $el . textContent ) . toBe ( '1, 2' ) ;
275
+ vm . form = { a : 2 , b : 3 } ;
276
+ waitForUpdate ( ( ) => {
277
+ expect ( vm . $el . textContent ) . toBe ( '2, 3' ) ;
278
+ } ) . then ( done ) ;
279
+ } )
239
280
} ) ;
You can’t perform that action at this time.
0 commit comments