From 1526f94edf023899490d7c58afcf36b051e25b6c Mon Sep 17 00:00:00 2001 From: Evan You Date: Tue, 25 May 2021 11:10:11 -0400 Subject: [PATCH] fix(watch): should not leak this context to setup watch getters ref #3603 --- .../runtime-core/__tests__/apiWatch.spec.ts | 18 +++++++++++++++++- packages/runtime-core/src/apiWatch.ts | 10 +++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/packages/runtime-core/__tests__/apiWatch.spec.ts b/packages/runtime-core/__tests__/apiWatch.spec.ts index aed7d65b6..28f06057b 100644 --- a/packages/runtime-core/__tests__/apiWatch.spec.ts +++ b/packages/runtime-core/__tests__/apiWatch.spec.ts @@ -878,6 +878,22 @@ describe('api: watch', () => { expect(source).toHaveBeenCalledWith(instance) }) + test('should not leak `this.proxy` to setup()', () => { + const source = jest.fn() + + const Comp = defineComponent({ + render() {}, + setup() { + watch(source, () => {}) + } + }) + + const root = nodeOps.createElement('div') + createApp(Comp).mount(root) + // should not have any arguments + expect(source.mock.calls[0]).toMatchObject([]) + }) + // #2728 test('pre watcher callbacks should not track dependencies', async () => { const a = ref(0) @@ -944,7 +960,7 @@ describe('api: watch', () => { await nextTick() expect(spy).toHaveBeenCalledTimes(2) }) - + it('watching sources: ref', async () => { const foo = ref([1]) const spy = jest.fn() diff --git a/packages/runtime-core/src/apiWatch.ts b/packages/runtime-core/src/apiWatch.ts index 41ded8784..0e33193b2 100644 --- a/packages/runtime-core/src/apiWatch.ts +++ b/packages/runtime-core/src/apiWatch.ts @@ -189,9 +189,7 @@ function doWatch( } else if (isReactive(s)) { return traverse(s) } else if (isFunction(s)) { - return callWithErrorHandling(s, instance, ErrorCodes.WATCH_GETTER, [ - instance && (instance.proxy as any) - ]) + return callWithErrorHandling(s, instance, ErrorCodes.WATCH_GETTER) } else { __DEV__ && warnInvalidSource(s) } @@ -200,9 +198,7 @@ function doWatch( if (cb) { // getter with cb getter = () => - callWithErrorHandling(source, instance, ErrorCodes.WATCH_GETTER, [ - instance && (instance.proxy as any) - ]) + callWithErrorHandling(source, instance, ErrorCodes.WATCH_GETTER) } else { // no cb -> simple effect getter = () => { @@ -371,7 +367,7 @@ export function instanceWatch( ? source.includes('.') ? createPathGetter(publicThis, source) : () => publicThis[source] - : source.bind(publicThis) + : source.bind(publicThis, publicThis) let cb if (isFunction(value)) { cb = value