Skip to content

Commit

Permalink
fix(vm): ensure custom properties can be set and read
Browse files Browse the repository at this point in the history
  • Loading branch information
LinusBorg committed Nov 17, 2022
1 parent caef933 commit 784882f
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 10 deletions.
26 changes: 25 additions & 1 deletion src/__tests__/lifecylce.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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: `<div/>`,
}
)

expect((wrapper.vm as any).custom).toBe('A')
})
})
4 changes: 2 additions & 2 deletions src/createComposable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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))
Expand Down
11 changes: 7 additions & 4 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -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'
Expand All @@ -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
)
Expand Down
6 changes: 3 additions & 3 deletions src/vmContextProxy.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import type { ComponentPublicInstance } from 'vue'

export /* #__PURE__ */ function createContextProxy(
vm: ComponentPublicInstance,
_vm: ComponentPublicInstance,
context: Record<string, any>
) {
return new Proxy(vm, {
return new Proxy(_vm, {
get(vm, key, receiver) {
if (key in context) {
return Reflect.get(context, key, receiver)
} else {
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 {
Expand Down

0 comments on commit 784882f

Please sign in to comment.