From cfa18c2b8ef6212a0928ae3e182620e98abf6d3a Mon Sep 17 00:00:00 2001 From: Netfan Date: Mon, 10 Mar 2025 02:06:22 +0800 Subject: [PATCH] fix: improve component repackaging --- apps/web-antd/src/adapter/component/index.ts | 33 +++++++++++++++---- apps/web-ele/src/adapter/component/index.ts | 32 ++++++++++++++---- apps/web-naive/src/adapter/component/index.ts | 33 +++++++++++++++---- playground/src/adapter/component/index.ts | 33 +++++++++++++++---- 4 files changed, 107 insertions(+), 24 deletions(-) diff --git a/apps/web-antd/src/adapter/component/index.ts b/apps/web-antd/src/adapter/component/index.ts index a541a845..f382880a 100644 --- a/apps/web-antd/src/adapter/component/index.ts +++ b/apps/web-antd/src/adapter/component/index.ts @@ -3,11 +3,12 @@ * 可用于 vben-form、vben-modal、vben-drawer 等组件使用, */ -import type { Component, SetupContext } from 'vue'; +import type { Component } from 'vue'; import type { BaseFormComponentType } from '@vben/common-ui'; +import type { Recordable } from '@vben/types'; -import { h } from 'vue'; +import { defineComponent, getCurrentInstance, h, ref } from 'vue'; import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; @@ -41,10 +42,30 @@ const withDefaultPlaceholder = ( component: T, type: 'input' | 'select', ) => { - return (props: any, { attrs, slots }: Omit) => { - const placeholder = props?.placeholder || $t(`ui.placeholder.${type}`); - return h(component, { ...props, ...attrs, placeholder }, slots); - }; + return defineComponent({ + inheritAttrs: false, + name: component.name, + setup: (props: any, { attrs, expose, slots }) => { + const placeholder = + props?.placeholder || + attrs?.placeholder || + $t(`ui.placeholder.${type}`); + // 透传组件暴露的方法 + const innerRef = ref(); + const publicApi: Recordable = {}; + expose(publicApi); + const instance = getCurrentInstance(); + instance?.proxy?.$nextTick(() => { + for (const key in innerRef.value) { + if (typeof innerRef.value[key] === 'function') { + publicApi[key] = innerRef.value[key]; + } + } + }); + return () => + h(component, { ...props, ...attrs, placeholder, ref: innerRef }, slots); + }, + }); }; // 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明 diff --git a/apps/web-ele/src/adapter/component/index.ts b/apps/web-ele/src/adapter/component/index.ts index 6152ed31..5de86aa5 100644 --- a/apps/web-ele/src/adapter/component/index.ts +++ b/apps/web-ele/src/adapter/component/index.ts @@ -3,12 +3,12 @@ * 可用于 vben-form、vben-modal、vben-drawer 等组件使用, */ -import type { Component, SetupContext } from 'vue'; +import type { Component } from 'vue'; import type { BaseFormComponentType } from '@vben/common-ui'; import type { Recordable } from '@vben/types'; -import { h } from 'vue'; +import { defineComponent, getCurrentInstance, h, ref } from 'vue'; import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; @@ -38,10 +38,30 @@ const withDefaultPlaceholder = ( component: T, type: 'input' | 'select', ) => { - return (props: any, { attrs, slots }: Omit) => { - const placeholder = props?.placeholder || $t(`ui.placeholder.${type}`); - return h(component, { ...props, ...attrs, placeholder }, slots); - }; + return defineComponent({ + inheritAttrs: false, + name: component.name, + setup: (props: any, { attrs, expose, slots }) => { + const placeholder = + props?.placeholder || + attrs?.placeholder || + $t(`ui.placeholder.${type}`); + // 透传组件暴露的方法 + const innerRef = ref(); + const publicApi: Recordable = {}; + expose(publicApi); + const instance = getCurrentInstance(); + instance?.proxy?.$nextTick(() => { + for (const key in innerRef.value) { + if (typeof innerRef.value[key] === 'function') { + publicApi[key] = innerRef.value[key]; + } + } + }); + return () => + h(component, { ...props, ...attrs, placeholder, ref: innerRef }, slots); + }, + }); }; // 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明 diff --git a/apps/web-naive/src/adapter/component/index.ts b/apps/web-naive/src/adapter/component/index.ts index a8415900..83430d8c 100644 --- a/apps/web-naive/src/adapter/component/index.ts +++ b/apps/web-naive/src/adapter/component/index.ts @@ -3,11 +3,12 @@ * 可用于 vben-form、vben-modal、vben-drawer 等组件使用, */ -import type { Component, SetupContext } from 'vue'; +import type { Component } from 'vue'; import type { BaseFormComponentType } from '@vben/common-ui'; +import type { Recordable } from '@vben/types'; -import { h } from 'vue'; +import { defineComponent, getCurrentInstance, h, ref } from 'vue'; import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; @@ -37,10 +38,30 @@ const withDefaultPlaceholder = ( component: T, type: 'input' | 'select', ) => { - return (props: any, { attrs, slots }: Omit) => { - const placeholder = props?.placeholder || $t(`ui.placeholder.${type}`); - return h(component, { ...props, ...attrs, placeholder }, slots); - }; + return defineComponent({ + inheritAttrs: false, + name: component.name, + setup: (props: any, { attrs, expose, slots }) => { + const placeholder = + props?.placeholder || + attrs?.placeholder || + $t(`ui.placeholder.${type}`); + // 透传组件暴露的方法 + const innerRef = ref(); + const publicApi: Recordable = {}; + expose(publicApi); + const instance = getCurrentInstance(); + instance?.proxy?.$nextTick(() => { + for (const key in innerRef.value) { + if (typeof innerRef.value[key] === 'function') { + publicApi[key] = innerRef.value[key]; + } + } + }); + return () => + h(component, { ...props, ...attrs, placeholder, ref: innerRef }, slots); + }, + }); }; // 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明 diff --git a/playground/src/adapter/component/index.ts b/playground/src/adapter/component/index.ts index 607130b3..6a2dc750 100644 --- a/playground/src/adapter/component/index.ts +++ b/playground/src/adapter/component/index.ts @@ -3,11 +3,12 @@ * 可用于 vben-form、vben-modal、vben-drawer 等组件使用, */ -import type { Component, SetupContext } from 'vue'; +import type { Component } from 'vue'; import type { BaseFormComponentType } from '@vben/common-ui'; +import type { Recordable } from '@vben/types'; -import { h } from 'vue'; +import { defineComponent, getCurrentInstance, h, ref } from 'vue'; import { ApiComponent, globalShareState, IconPicker } from '@vben/common-ui'; import { $t } from '@vben/locales'; @@ -41,10 +42,30 @@ const withDefaultPlaceholder = ( component: T, type: 'input' | 'select', ) => { - return (props: any, { attrs, slots }: Omit) => { - const placeholder = props?.placeholder || $t(`ui.placeholder.${type}`); - return h(component, { ...props, ...attrs, placeholder }, slots); - }; + return defineComponent({ + inheritAttrs: false, + name: component.name, + setup: (props: any, { attrs, expose, slots }) => { + const placeholder = + props?.placeholder || + attrs?.placeholder || + $t(`ui.placeholder.${type}`); + // 透传组件暴露的方法 + const innerRef = ref(); + const publicApi: Recordable = {}; + expose(publicApi); + const instance = getCurrentInstance(); + instance?.proxy?.$nextTick(() => { + for (const key in innerRef.value) { + if (typeof innerRef.value[key] === 'function') { + publicApi[key] = innerRef.value[key]; + } + } + }); + return () => + h(component, { ...props, ...attrs, placeholder, ref: innerRef }, slots); + }, + }); }; // 这里需要自行根据业务组件库进行适配,需要用到的组件都需要在这里类型说明