diff --git a/docs/guide/form-dialog.md b/docs/guide/form-dialog.md index f424fe3..0949fdb 100644 --- a/docs/guide/form-dialog.md +++ b/docs/guide/form-dialog.md @@ -42,7 +42,7 @@ type IFormDialogProps = Omit & { okText?: string | Component | VNode | (() => VNode) okButtonProps?: ButtonProps onOpen?: () => void - onOpend?: () => void + onOpened?: () => void onClose?: () => void onClosed?: () => void onCancel?: () => void diff --git a/package.json b/package.json index 2971003..ee147d8 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,9 @@ "workspaces": [ "packages/*" ], + "resolutions": { + "**/rollup-plugin-typescript2": "^0.31.0" + }, "scripts": { "start": "vuepress dev docs", "build": "formily-tpl build", @@ -105,5 +108,6 @@ }, "peerDependencies": { "vue": "^3.2.24" - } + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/packages/components/src/__builtins__/shared/portal.ts b/packages/components/src/__builtins__/shared/portal.ts index c804d21..7a3ca15 100644 --- a/packages/components/src/__builtins__/shared/portal.ts +++ b/packages/components/src/__builtins__/shared/portal.ts @@ -1,4 +1,4 @@ -import { defineComponent, onBeforeUnmount } from 'vue' +import { defineComponent, getCurrentInstance, onBeforeUnmount } from 'vue' import { h, Fragment } from '@formily/vue' export interface IPortalProps { id?: string | symbol @@ -16,22 +16,21 @@ export const createPortalProvider = (id: string | symbol) => { }, }, - setup(props) { + setup(props, { slots }) { + const { appContext } = getCurrentInstance() + + if (props.id && !PortalMap.has(props.id)) { + PortalMap.set(props.id, appContext) + } + onBeforeUnmount(() => { const { id } = props if (id && PortalMap.has(id)) { PortalMap.delete(id) } }) - }, - - render() { - const { id } = this - if (id && !PortalMap.has(id)) { - PortalMap.set(id, this) - } - return h(Fragment, {}, this.$slots) + return () => h(Fragment, {}, slots) }, }) diff --git a/packages/components/src/form-dialog/index.ts b/packages/components/src/form-dialog/index.ts index f804ef7..3a4f27b 100644 --- a/packages/components/src/form-dialog/index.ts +++ b/packages/components/src/form-dialog/index.ts @@ -19,12 +19,14 @@ import { Component, VNode, defineComponent, + nextTick, Teleport, - createApp, + createVNode, PropType, h, onMounted, ref, + render as vueRender, } from 'vue' import { isValidElement, @@ -50,7 +52,7 @@ type IFormDialogProps = Omit & { okButtonProps?: typeof ElButtonProps beforeClose?: (cb: Function) => void onOpen?: () => void - onOpend?: () => void + onOpened?: () => void onClose?: () => void onClosed?: () => void onCancel?: () => void @@ -120,7 +122,6 @@ export function FormDialog( root: document.createElement('div'), form: null, promise: null, - app: null, instance: null, openMiddlewares: [], confirmMiddlewares: [], @@ -134,8 +135,7 @@ export function FormDialog( ...props, onClosed: () => { props.onClosed?.() - env.app?.unmount?.() - env.app = null + vueRender(null, env.root) env.instance = null env.root?.parentNode?.removeChild(env.root) env.root = undefined @@ -161,135 +161,137 @@ export function FormDialog( ) const render = (visible = true, resolve?: () => any, reject?: () => any) => { - if (!env.instance) { - const ComponentConstructor = observer( - defineComponent({ - props: { dialogProps: Object as PropType }, - data() { - return { - visible: false, - } - }, - render() { - const { - onClose, - onClosed, - onOpen, - onOpend, - onOK, - onCancel, - title, - footer, - okText, - cancelText, - okButtonProps, - cancelButtonProps, - ...dialogProps - } = this.dialogProps - - return h( - ElDialog, + if (env.instance) { + env.instance.visible = visible + return + } + + const ComponentConstructor = observer( + defineComponent({ + props: { dialogProps: Object as PropType }, + data() { + return { + visible: false, + } + }, + render() { + const { + onClose, + onClosed, + onOpen, + onOpened, + onOK, + onCancel, + title, + footer, + okText, + cancelText, + okButtonProps, + cancelButtonProps, + ...dialogProps + } = this.dialogProps + + const renderFooter = () => { + const FooterPortalTarget = h( + 'span', { - class: [`${prefixCls}`], - ...dialogProps, - modelValue: this.visible, - 'onUpdate:modelValue': (val) => { - this.visible = val - }, - onClose: () => { - onClose?.() - }, - onClosed: () => { - onClosed?.() - }, - onOpen: () => { - onOpen?.() - }, - onOpened: () => { - onOpend?.() - }, + id: PORTAL_TARGET_NAME, }, - { - default: () => - h(FormProvider, { form: env.form }, () => - h(component, {}, {}) - ), - title: () => - h('div', {}, { default: () => resolveComponent(title) }), - footer: () => - h( - 'div', - {}, - { - default: () => { - const FooterPortalTarget = h( - 'span', - { - id: PORTAL_TARGET_NAME, - }, - {} - ) - if (footer === null) { - return [null, FooterPortalTarget] - } else if (footer) { - return [resolveComponent(footer), FooterPortalTarget] - } - - return [ - h( - ElButton, - { - ...cancelButtonProps, - onClick: (e) => { - onCancel?.(e) - reject() - }, - }, - { - default: () => - resolveComponent( - cancelText || '取消' - // t('el.popconfirm.cancelButtonText') - ), - } - ), - h( - ElButton, - { - type: 'primary', - ...okButtonProps, - loading: env.form.submitting, - onClick: (e) => { - onOK?.(e) - resolve() - }, - }, - { - default: () => - resolveComponent( - okText || '确定' - // t('el.popconfirm.confirmButtonText') - ), - } - ), - FooterPortalTarget, - ] - }, - } - ), - } + {} ) - }, - }) - ) - env.app = createApp(ComponentConstructor, { - dialogProps, - parent: getPortalContext(id as string | symbol), + if (footer === null) { + return [null, FooterPortalTarget] + } + + if (footer) { + return [resolveComponent(footer), FooterPortalTarget] + } + + return [ + h( + ElButton, + { + ...cancelButtonProps, + onClick: () => { + onCancel?.() + reject() + }, + }, + { + default: () => resolveComponent(cancelText || '取消'), + } + ), + h( + ElButton, + { + type: 'primary', + ...okButtonProps, + loading: env.form.submitting, + onClick: () => { + onOK?.() + resolve() + }, + }, + { + default: () => resolveComponent(okText || '确定'), + } + ), + FooterPortalTarget, + ] + } + + return h( + ElDialog, + { + class: [`${prefixCls}`], + ...dialogProps, + modelValue: this.visible, + 'onUpdate:modelValue': (val) => { + this.visible = val + }, + onClose, + onClosed, + onOpen, + onOpened, + title: isStr(title) ? title : undefined, + }, + { + default: () => + h(FormProvider, { form: env.form }, () => h(component, {}, {})), + header: !isStr(title) + ? (slotProps) => + h( + 'div', + {}, + { default: () => resolveComponent(title, slotProps) } + ) + : undefined, + footer: () => + h( + 'div', + {}, + { + default: renderFooter, + } + ), + } + ) + }, }) - env.instance = env.app.mount(env.root) - } - env.instance.visible = visible + ) + + const vnode = createVNode(ComponentConstructor, { + dialogProps: dialogProps, + }) + + vnode.appContext = getPortalContext(id as string | symbol) + vueRender(vnode, env.root) + + nextTick(() => { + env.instance = vnode.component.proxy + env.instance.visible = visible + }) } const formDialog = { diff --git a/yarn.lock b/yarn.lock index 2f3166b..48d63b2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2191,7 +2191,7 @@ estree-walker "^1.0.1" picomatch "^2.2.2" -"@rollup/pluginutils@^4.0.0", "@rollup/pluginutils@^4.1.0", "@rollup/pluginutils@^4.1.2", "@rollup/pluginutils@^4.2.0": +"@rollup/pluginutils@^4.0.0", "@rollup/pluginutils@^4.1.2", "@rollup/pluginutils@^4.2.0": version "4.2.1" resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d" integrity sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ== @@ -6729,7 +6729,7 @@ find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-cache-dir@^3.3.1, find-cache-dir@^3.3.2: +find-cache-dir@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== @@ -6908,15 +6908,6 @@ fs-exists-sync@^0.1.0: resolved "https://registry.yarnpkg.com/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz#982d6893af918e72d08dec9e8673ff2b5a8d6add" integrity sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg== -fs-extra@8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - fs-extra@^10.0.0: version "10.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" @@ -8134,7 +8125,7 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.2.0, is-core-module@^2.5.0: +is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.5.0: version "2.14.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.14.0.tgz#43b8ef9f46a6a08888db67b1ffd4ec9e3dfd59d1" integrity sha512-a5dFJih5ZLYlRtDc0dZWP7RiKr6xIKzmn/oAYCDvdLThadVgyJwlaoQPmRtMSpz+rk0OGAgIu+TcM9HUF0fk1A== @@ -9283,13 +9274,6 @@ jsonfile@^3.0.0: optionalDependencies: graceful-fs "^4.1.6" -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== - optionalDependencies: - graceful-fs "^4.1.6" - jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -11472,7 +11456,7 @@ path-key@^4.0.0: resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== -path-parse@^1.0.6, path-parse@^1.0.7: +path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -12596,14 +12580,6 @@ resolve.exports@^1.1.0: resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== -resolve@1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== - dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" - resolve@>=1.9.0, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.1, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.4: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" @@ -12763,20 +12739,9 @@ rollup-plugin-terser@^7.0.2: serialize-javascript "^4.0.0" terser "^5.0.0" -rollup-plugin-typescript2@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.30.0.tgz#1cc99ac2309bf4b9d0a3ebdbc2002aecd56083d3" - integrity sha512-NUFszIQyhgDdhRS9ya/VEmsnpTe+GERDMmFo0Y+kf8ds51Xy57nPNGglJY+W6x1vcouA7Au7nsTgsLFj2I0PxQ== - dependencies: - "@rollup/pluginutils" "^4.1.0" - find-cache-dir "^3.3.1" - fs-extra "8.1.0" - resolve "1.20.0" - tslib "2.1.0" - -rollup-plugin-typescript2@^0.31.2: +rollup-plugin-typescript2@^0.30.0, rollup-plugin-typescript2@^0.31.0, rollup-plugin-typescript2@^0.31.2: version "0.31.2" - resolved "https://registry.yarnpkg.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.31.2.tgz#463aa713a7e2bf85b92860094b9f7fb274c5a4d8" + resolved "https://registry.npmmirror.com/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.31.2.tgz#463aa713a7e2bf85b92860094b9f7fb274c5a4d8" integrity sha512-hRwEYR1C8xDGVVMFJQdEVnNAeWRvpaY97g5mp3IeLnzhNXzSVq78Ye/BJ9PAaUfN4DXa/uDnqerifMOaMFY54Q== dependencies: "@rollup/pluginutils" "^4.1.2" @@ -14235,11 +14200,6 @@ tsconfig-paths@^3.15.0: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== - tslib@^1.8.1, tslib@^1.9.0: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"