diff --git a/src/utils/instance.ts b/src/utils/instance.ts index 3ee24edc..5fa4e4b7 100644 --- a/src/utils/instance.ts +++ b/src/utils/instance.ts @@ -1,7 +1,7 @@ import { ComponentInstance } from '../component' import vmStateManager from './vmStateManager' import { setCurrentInstance, getCurrentVue2Instance } from '../runtimeContext' -import { Ref, isRef } from '../apis' +import { Ref, isRef, isReactive } from '../apis' import { hasOwn, proxy, warn } from './utils' import { createSlotProxy, resolveSlots } from './helper' @@ -20,8 +20,19 @@ export function asVmProperty( }, }) } else { - // @ts-ignore - vm[propName] = propValue + Object.defineProperty(vm, propName, { + enumerable: true, + configurable: true, + get: () => { + if (isReactive(propValue)) { + ;(propValue as any).__ob__.dep.depend() + } + return propValue + }, + set: (val) => { + propValue = val + }, + }) } if (__DEV__) { diff --git a/test/setup.spec.js b/test/setup.spec.js index 35329849..2bcbe442 100644 --- a/test/setup.spec.js +++ b/test/setup.spec.js @@ -13,6 +13,8 @@ const { isReactive, defineComponent, onMounted, + set, + del, } = require('../src') const { sleep } = require('./helpers/utils') @@ -896,6 +898,42 @@ describe('setup', () => { expect(vm.$el.textContent).toBe('2') }) + // #683 #603 #580 + it('should update directly when adding attributes to a reactive object', async () => { + const vm = new Vue({ + template: '