diff --git a/packages/runtime-core/src/componentPublicInstance.ts b/packages/runtime-core/src/componentPublicInstance.ts index c2d36e77151..018187fc642 100644 --- a/packages/runtime-core/src/componentPublicInstance.ts +++ b/packages/runtime-core/src/componentPublicInstance.ts @@ -356,7 +356,9 @@ export const PublicInstanceProxyHandlers: ProxyHandler = { return desc.get.call(instance.proxy) } else { const val = globalProperties[key] - return isFunction(val) ? val.bind(instance.proxy) : val + return isFunction(val) + ? Object.assign(val.bind(instance.proxy), val) + : val } } else { return globalProperties[key] diff --git a/packages/vue-compat/__tests__/global.spec.ts b/packages/vue-compat/__tests__/global.spec.ts index 86bb4391092..06109a67f64 100644 --- a/packages/vue-compat/__tests__/global.spec.ts +++ b/packages/vue-compat/__tests__/global.spec.ts @@ -285,6 +285,28 @@ describe('GLOBAL_PROTOTYPE', () => { delete Vue.prototype.$test }) + test.only('functions keeps additional properties', () => { + function test(this: any) { + return this.msg + } + test.additionalFn = () => { + return 'additional fn' + } + + Vue.prototype.$test = test + const vm = new Vue({ + data() { + return { + msg: 'test' + } + } + }) as any + expect(typeof vm.$test).toBe('function') + expect(typeof vm.$test.additionalFn).toBe('function') + expect(vm.$test.additionalFn()).toBe('additional fn') + delete Vue.prototype.$test + }) + test('extended prototype', async () => { const Foo = Vue.extend() Foo.prototype.$test = 1