From 784882febd52ee3c3e07d0ab1b19285c44609b22 Mon Sep 17 00:00:00 2001 From: Thorsten Luenborg Date: Thu, 17 Nov 2022 22:11:16 +0100 Subject: [PATCH] fix(vm): ensure custom properties can be set and read --- src/__tests__/lifecylce.spec.ts | 26 +++++++++++++++++++++++++- src/createComposable.ts | 4 ++-- src/utils.ts | 11 +++++++---- src/vmContextProxy.ts | 6 +++--- 4 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/__tests__/lifecylce.spec.ts b/src/__tests__/lifecylce.spec.ts index 0948e89..60b9dd4 100644 --- a/src/__tests__/lifecylce.spec.ts +++ b/src/__tests__/lifecylce.spec.ts @@ -4,7 +4,7 @@ import { defineMixin } from '../defineMixin' import { wrapComposable } from './helpers' describe('Lifecycle hooks', async () => { - test('normal lifecycle hooks are called with proper `this`', async () => { + test('are called with proper `this`', async () => { const spy = vi.fn() function testHandler() { // @ts-expect-error - doesn't like this for some reason @@ -44,4 +44,28 @@ describe('Lifecycle hooks', async () => { expect(spy).toHaveBeenCalledTimes(8) }) + + test('can read and set custom properties on `this`', async () => { + const mixin = defineMixin({ + props: {}, + beforeCreate() { + ;(this as any).custom = 'A' + }, + created() { + expect((this as any).custom).toBe('A') + }, + }) + + const composable = createComposableFromMixin(mixin) + + const wrapper = wrapComposable( + composable, + {}, + { + template: `
`, + } + ) + + expect((wrapper.vm as any).custom).toBe('A') + }) }) diff --git a/src/createComposable.ts b/src/createComposable.ts index 9bb01fb..21063e0 100644 --- a/src/createComposable.ts +++ b/src/createComposable.ts @@ -140,7 +140,7 @@ export /* @__PURE__ */ function createComposableFromMixin< const reactiveContext = reactive(context) const vmContextProxy = createContextProxy(vm, reactiveContext) as VM - beforeCreate && callHook(beforeCreate, instance, 'bc') + beforeCreate && callHook(beforeCreate, instance, vm, 'bc') // methods if (methods) { @@ -204,7 +204,7 @@ export /* @__PURE__ */ function createComposableFromMixin< } // Lifecycle - created && callHook(created, instance, 'c') + created && callHook(created, instance, vm, 'c') beforeMount && onBeforeMount(beforeMount.bind(vm)) mounted && onMounted(mounted.bind(vm)) beforeUpdate && onBeforeUpdate(beforeUpdate.bind(vm)) diff --git a/src/utils.ts b/src/utils.ts index a54120c..2962b94 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,4 +1,8 @@ -import { callWithAsyncErrorHandling, type ComponentInternalInstance } from 'vue' +import { + callWithAsyncErrorHandling, + type ComponentInternalInstance, + type ComponentPublicInstance, +} from 'vue' export const isFunction = (val: unknown): val is Function => typeof val === 'function' @@ -15,12 +19,11 @@ export const isString = (val: unknown): val is string => typeof val === 'string' export function callHook( hook: Function, instance: ComponentInternalInstance, + vm: ComponentPublicInstance, type: 'c' | 'bc' ) { callWithAsyncErrorHandling( - isArray(hook) - ? hook.map((h) => h.bind(instance.proxy!)) - : hook.bind(instance.proxy!), + isArray(hook) ? hook.map((h) => h.bind(vm)) : hook.bind(vm), instance, type as any ) diff --git a/src/vmContextProxy.ts b/src/vmContextProxy.ts index ab926e3..d1c1c19 100644 --- a/src/vmContextProxy.ts +++ b/src/vmContextProxy.ts @@ -1,10 +1,10 @@ import type { ComponentPublicInstance } from 'vue' export /* #__PURE__ */ function createContextProxy( - vm: ComponentPublicInstance, + _vm: ComponentPublicInstance, context: Record ) { - return new Proxy(vm, { + return new Proxy(_vm, { get(vm, key, receiver) { if (key in context) { return Reflect.get(context, key, receiver) @@ -12,7 +12,7 @@ export /* #__PURE__ */ function createContextProxy( return (vm as any)[key] } }, - set(m, key, value, receiver) { + set(vm, key, value, receiver) { if (key in context) { return Reflect.set(context, key, value, receiver) } else {