Skip to content

Commit 5897660

Browse files
committed
🐛 Bind methods accessed by data
Consider a component like this: ```typescript @component class MyComponent { foo = 'foo' options = { handler = this.method, } method() { return this.foo } } ``` When we call `options.handler()`, we would expect to get back `foo`, but this currently doesn't work, because the methods aren't correctly bound in the data builder function. This change actively binds the functions to the Vue component instance, so that the above example works as expected.
1 parent 48d118d commit 5897660

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

src/index.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,16 @@ export const Base = class {
4040
})
4141
}
4242

43+
const methods = optionBuilder.methods
44+
if (methods) {
45+
Object.keys(methods).forEach(key => {
46+
(this as any)[key] = methods[key].bind(vueInstance)
47+
})
48+
}
4349
}
4450

4551
} as VueCons
4652

4753
export const Vue = Base
4854

49-
export { toNative } from './component'
55+
export { toNative } from './component'

src/option/data.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import { makeObject, obtainSlot, excludeNames, getValidNames } from '../utils'
44

55
export function build(cons: Cons, optionBuilder: OptionBuilder, vueInstance: any) {
66
optionBuilder.data ??= {}
7-
const sample = new cons(optionBuilder,vueInstance)
8-
let names = getValidNames(sample, (des) => {
9-
return !!des.enumerable
7+
const sample = new cons(optionBuilder, vueInstance) as any
8+
let names = getValidNames(sample, (des, name) => {
9+
return !!des.enumerable && !optionBuilder.methods?.[name]
1010
})
1111
const slot = obtainSlot(cons.prototype)
1212
names = excludeNames(names, slot)

test/option/data.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ class Comp extends Base {
1111
@Prop
1212
prop!: string
1313
fieldInitProp = this.prop //not work
14+
15+
methods = [this.method];
16+
options = {
17+
handler: this.method,
18+
}
19+
wrapped = () => this.method();
20+
21+
method() {
22+
return this.data
23+
}
1424
}
1525

1626
const CompContext = toNative(Comp) as any
@@ -25,9 +35,16 @@ describe('option data',
2535

2636
expect('function').to.equal(typeof CompContext?.data)
2737
expect('data value').to.equal(CompContext.data().data)
28-
expect(2).to.equal(Object.keys(CompContext.data()).length)
38+
expect(5).to.equal(Object.keys(CompContext.data()).length)
2939
// expect('prop test').to.equal(vm.fieldInitProp)
3040
})
41+
42+
it('binds methods to the component context', () => {
43+
const {vm} = mount(CompContext)
44+
expect('data value').to.equal(vm.methods[0]())
45+
expect('data value').to.equal(vm.options.handler())
46+
expect('data value').to.equal(vm.wrapped())
47+
})
3148
}
3249
)
3350
export default {}

0 commit comments

Comments
 (0)