Skip to content

Commit a7f2c25

Browse files
authored
fix(setup): handle updates for directly return a reactive object (#488)
* fix(setup): handle updates for directly return a reactive object, fix #487 * chore: type fix
1 parent 76f1f8f commit a7f2c25

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

Diff for: src/mixin.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
SetupFunction,
66
Data,
77
} from './component'
8-
import { isRef, isReactive, markRaw, markReactive } from './reactivity'
8+
import { isRef, isReactive, markRaw, markReactive, toRefs } from './reactivity'
99
import { isPlainObject, assert, proxy, warn, isFunction } from './utils'
1010
import { ref } from './apis'
1111
import vmStateManager from './utils/vmStateManager'
@@ -94,13 +94,16 @@ export function mixin(Vue: VueConstructor) {
9494
return activateCurrentInstance(vm, () => bindingFunc())
9595
}
9696
return
97-
}
98-
if (isPlainObject(binding)) {
97+
} else if (isPlainObject(binding)) {
98+
if (isReactive(binding)) {
99+
binding = toRefs(binding) as Data
100+
}
101+
99102
const bindingObj = binding
100103
vmStateManager.set(vm, 'rawBindings', binding)
101104

102105
Object.keys(binding).forEach((name) => {
103-
let bindingValue = bindingObj[name]
106+
let bindingValue: any = bindingObj[name]
104107
// only make primitive value reactive
105108
if (!isRef(bindingValue)) {
106109
if (isReactive(bindingValue)) {

Diff for: test/helpers/utils.ts

+4
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,7 @@ const Vue = require('vue/dist/vue.common.js')
33
export function nextTick(): Promise<any> {
44
return Vue.nextTick()
55
}
6+
7+
export function sleep(ms = 100) {
8+
return new Promise((resolve) => setTimeout(resolve, ms))
9+
}

Diff for: test/setup.spec.js

+25
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ const {
99
toRefs,
1010
markRaw,
1111
toRaw,
12+
nextTick,
1213
} = require('../src')
14+
const { sleep } = require('./helpers/utils')
1315

1416
describe('setup', () => {
1517
beforeEach(() => {
@@ -861,4 +863,27 @@ describe('setup', () => {
861863
const vm = new Vue(Constructor).$mount()
862864
expect(vm.$el.textContent).toBe('Composition-api')
863865
})
866+
867+
// #487
868+
it('should handle updates for directly return a reactive object.', async () => {
869+
const opts = {
870+
template: '<div>{{ count }}</div>',
871+
setup() {
872+
const state = reactive({ count: 1 })
873+
874+
setTimeout(() => {
875+
state.count = 2
876+
}, 1)
877+
878+
return state
879+
},
880+
}
881+
const Constructor = Vue.extend(opts).extend({})
882+
883+
const vm = new Vue(Constructor).$mount()
884+
expect(vm.$el.textContent).toBe('1')
885+
await sleep(10)
886+
await nextTick()
887+
expect(vm.$el.textContent).toBe('2')
888+
})
864889
})

0 commit comments

Comments
 (0)