From 1f0707548652b5a69cc307060976fe54cba025cb Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Fri, 19 Jun 2020 14:06:04 +0100 Subject: [PATCH] fix: unwrap refs returned by `data` (#387) * fix: unwrap refs returned by `data` * chore: add a new test --- src/setup.ts | 28 ++++++++++++++++------------ test/setup.spec.js | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 12 deletions(-) diff --git a/src/setup.ts b/src/setup.ts index b1a40ae2..bcb93b7d 100644 --- a/src/setup.ts +++ b/src/setup.ts @@ -154,6 +154,22 @@ export function mixin(Vue: VueConstructor) { } } + const { data } = $options + // wrapper the data option, so we can invoke setup before data get resolved + $options.data = function wrappedData() { + if (setup) { + initSetup(vm, vm.$props) + } + const dataValue = + typeof data === 'function' + ? (data as ( + this: ComponentInstance, + x: ComponentInstance + ) => object).call(vm, vm) + : data || {} + return unwrapRefProxy(dataValue) + } + if (!setup) { return } @@ -166,18 +182,6 @@ export function mixin(Vue: VueConstructor) { } return } - - const { data } = $options - // wrapper the data option, so we can invoke setup before data get resolved - $options.data = function wrappedData() { - initSetup(vm, vm.$props) - return typeof data === 'function' - ? (data as ( - this: ComponentInstance, - x: ComponentInstance - ) => object).call(vm, vm) - : data || {} - } } function initSetup(vm: ComponentInstance, props: Record = {}) { diff --git a/test/setup.spec.js b/test/setup.spec.js index 497f8bb6..5d0ad820 100644 --- a/test/setup.spec.js +++ b/test/setup.spec.js @@ -84,6 +84,19 @@ describe('setup', () => { expect(vm.b).toBe(1) }) + // #385 + it('should unwrapRef on data', () => { + const vm = new Vue({ + data() { + return { + a: ref(1), + } + }, + setup() {}, + }).$mount() + expect(vm.a).toBe(1) + }) + it('should work with `methods` and `data` options', (done) => { let calls = 0 const vm = new Vue({ @@ -756,4 +769,37 @@ describe('setup', () => { const vm = new Vue(Constructor).$mount() expect(vm.$el.textContent).toBe('Composition-api') }) + + it('should keep data reactive', async () => { + const vm = new Vue({ + template: `
+ + +
`, + data() { + return { + a: 1, + b: ref(1), + } + }, + }).$mount() + + const a = vm.$el.querySelector('#a') + const b = vm.$el.querySelector('#b') + + expect(a.textContent).toBe('1') + expect(b.textContent).toBe('1') + + a.click() + await Vue.nextTick() + + expect(a.textContent).toBe('2') + expect(b.textContent).toBe('1') + + b.click() + await Vue.nextTick() + + expect(a.textContent).toBe('2') + expect(b.textContent).toBe('2') + }) })