From 6ba1331eb5db65d2f79549383207c82590d8e50a Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Fri, 2 Jun 2023 16:17:24 +0200 Subject: [PATCH 1/2] fix: handle views imported in script setup --- demo/app/components/FragmentRootComponent.vue | 5 ++ demo/app/components/GH1017.vue | 21 ++++++++ src/index.ts | 48 ++++++++++++++++++- 3 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 demo/app/components/FragmentRootComponent.vue create mode 100644 demo/app/components/GH1017.vue diff --git a/demo/app/components/FragmentRootComponent.vue b/demo/app/components/FragmentRootComponent.vue new file mode 100644 index 00000000..830fc81e --- /dev/null +++ b/demo/app/components/FragmentRootComponent.vue @@ -0,0 +1,5 @@ + diff --git a/demo/app/components/GH1017.vue b/demo/app/components/GH1017.vue new file mode 100644 index 00000000..740186ec --- /dev/null +++ b/demo/app/components/GH1017.vue @@ -0,0 +1,21 @@ + + + + diff --git a/src/index.ts b/src/index.ts index 74ee2b82..c64dc89b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,12 @@ -import { resolveComponent as resolveComponentCore } from '@vue/runtime-core'; import type { CreateAppFunction } from '@vue/runtime-core'; +import { + createBaseVNode as createBaseVNodeCore, + createBlock as createBlockCore, + createElementBlock as createElementBlockCore, + createElementVNode as createElementVNodeCore, + createVNode as createVNodeCore, + resolveComponent as resolveComponentCore, +} from '@vue/runtime-core'; import { BUILT_IN_COMPONENTS } from './components'; @@ -106,3 +113,42 @@ export function resolveComponent(name: string, maybeSelReference: boolean) { const component = resolveComponentCore(name, maybeSelReference); return component; } + +/** + * Checks if the type has a constructor.name that matches a known view or built-in component + * If so, returns the name of the view or component. This allows {N} element imports to be + * used inside script setup context without requiring aliasing. + */ +function maybeConvertToKnownComponentOrViewName(type: any) { + const name = type?.prototype?.constructor?.name; + if (name) { + if (BUILT_IN_COMPONENTS[name]) { + return BUILT_IN_COMPONENTS[name]; + } + + if (isKnownView(name)) { + return name; + } + } + + return type; +} + +/** + * Wraps the original function and replaces the first argument if it matches + * a known view or built-in component. + */ +function wrapCreate(originalFunction: T): T { + return ((type: any, ...args: any) => { + return (originalFunction as any)( + maybeConvertToKnownComponentOrViewName(type), + ...args + ); + }) as T; +} + +export const createBaseVNode = wrapCreate(createBaseVNodeCore); +export const createBlock = wrapCreate(createBlockCore); +export const createElementBlock = wrapCreate(createElementBlockCore); +export const createElementVNode = wrapCreate(createElementVNodeCore); +export const createVNode: typeof createVNodeCore = wrapCreate(createVNodeCore); From f777ce5efd33985e63cc786b2b4b89748d3cc19f Mon Sep 17 00:00:00 2001 From: Igor Randjelovic Date: Fri, 2 Jun 2023 16:22:09 +0200 Subject: [PATCH 2/2] fix: remove createBaseVNode, not exported directly --- src/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/index.ts b/src/index.ts index c64dc89b..dadb8c74 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,5 @@ import type { CreateAppFunction } from '@vue/runtime-core'; import { - createBaseVNode as createBaseVNodeCore, createBlock as createBlockCore, createElementBlock as createElementBlockCore, createElementVNode as createElementVNodeCore, @@ -147,7 +146,6 @@ function wrapCreate(originalFunction: T): T { }) as T; } -export const createBaseVNode = wrapCreate(createBaseVNodeCore); export const createBlock = wrapCreate(createBlockCore); export const createElementBlock = wrapCreate(createElementBlockCore); export const createElementVNode = wrapCreate(createElementVNodeCore);