From: kazuya kawaguchi Date: Sun, 4 Jan 2026 05:57:54 +0000 (+0900) Subject: fix(runtime-core): support `uid` key for `useInstanceOption` (#14272) X-Git-Tag: v3.6.0-beta.2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=55bdcedfc567b1a697b4424102194ffbf51cd50c;p=thirdparty%2Fvuejs%2Fcore.git fix(runtime-core): support `uid` key for `useInstanceOption` (#14272) resolve vuejs/rfcs#814 --- diff --git a/packages/runtime-core/__tests__/componentCurrentInstance.spec.ts b/packages/runtime-core/__tests__/componentCurrentInstance.spec.ts new file mode 100644 index 0000000000..67b206c571 --- /dev/null +++ b/packages/runtime-core/__tests__/componentCurrentInstance.spec.ts @@ -0,0 +1,84 @@ +import { h, nodeOps, render, useInstanceOption } from '@vue/runtime-test' + +describe('useInstanceOption', () => { + test(`'ce' key`, () => { + let hasInstance: boolean | undefined + let ce: any + const Comp = { + setup() { + const option = useInstanceOption('ce', true) + hasInstance = option.hasInstance + ce = option.value + return () => null + }, + } + render(h(Comp), nodeOps.createElement('div')) + expect(hasInstance).toBe(true) + // custom element definition is not supported in test renderer, so check to access it is enough + expect(ce).toBeUndefined() + }) + + test(`'type' key`, () => { + let hasInstance: boolean | undefined + let type: any + const Comp = { + __i18n: { locale: 'en' }, // inject by custom blocks + setup() { + const option = useInstanceOption('type', true) + hasInstance = option.hasInstance + type = option.value + return () => null + }, + mounted() {}, + } + render(h(Comp), nodeOps.createElement('div')) + expect(hasInstance).toBe(true) + expect('setup' in type).toBe(true) + expect('mounted' in type).toBe(true) + expect(type.__i18n).toEqual({ locale: 'en' }) + }) + + test(`'uid' key`, () => { + let hasInstance: boolean | undefined + let uid: any + const Comp = { + setup() { + const option = useInstanceOption('uid', true) + hasInstance = option.hasInstance + uid = option.value + return () => null + }, + } + render(h(Comp), nodeOps.createElement('div')) + expect(hasInstance).toBe(true) + expect(typeof uid).toBe('number') + }) + + test('not allowed key', () => { + let hasInstance: boolean | undefined + let value: any + const Comp = { + setup() { + const option = useInstanceOption('foo' as any, true) + hasInstance = option.hasInstance + value = option.value + return () => null + }, + } + render(h(Comp), nodeOps.createElement('div')) + expect(hasInstance).toBe(true) + expect(value).toBeUndefined() + expect( + `useInstanceOption only accepts 'ce', 'type', 'uid' as key, got 'foo'.`, + ).toHaveBeenWarned() + }) + + test('not active instance', () => { + const { hasInstance, value } = useInstanceOption('type') + expect(hasInstance).toBe(false) + expect(value).toBeUndefined() + expect( + 'useInstanceOption called without an active component instance.', + ).toHaveBeenWarned() + }) +}) diff --git a/packages/runtime-core/src/componentCurrentInstance.ts b/packages/runtime-core/src/componentCurrentInstance.ts index d73f2b9fdb..48075acbe6 100644 --- a/packages/runtime-core/src/componentCurrentInstance.ts +++ b/packages/runtime-core/src/componentCurrentInstance.ts @@ -92,7 +92,7 @@ export const setCurrentInstance = ( } } -const internalOptions = ['ce', 'type'] as const +const internalOptions = ['ce', 'type', 'uid'] as const /** * @internal