From 9e9544bd70e5fda99e4cbad1665a4ba8f3663cc1 Mon Sep 17 00:00:00 2001 From: Hooray <304327508@qq.com> Date: Tue, 29 Jul 2025 00:57:46 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=20`useFaModal`?= =?UTF-8?q?=20=E5=92=8C=20`useFaDrawer`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ui/components/FaDrawer/index.ts | 71 ++++++++++++++++----------- src/ui/components/FaModal/index.ts | 76 +++++++++++++++++------------ 2 files changed, 88 insertions(+), 59 deletions(-) diff --git a/src/ui/components/FaDrawer/index.ts b/src/ui/components/FaDrawer/index.ts index 58d33762..433ebf64 100644 --- a/src/ui/components/FaDrawer/index.ts +++ b/src/ui/components/FaDrawer/index.ts @@ -1,5 +1,5 @@ import type { Component, HTMLAttributes } from 'vue' -import { isVNode } from 'vue' +import { createVNode, isVNode, render } from 'vue' import Drawer from './index.vue' export interface DrawerProps { @@ -59,36 +59,49 @@ export function useFaDrawer() { const container = document.createElement('div') const visible = ref(false) const options = reactive({ ...initialOptions }) - const app = createApp({ - render() { - return h(Drawer, Object.assign({ - 'id': useId(), - 'modelValue': visible.value, - 'onUpdate:modelValue': (val: boolean) => { - visible.value = val - }, - }, options), { - default: () => { - if (typeof options.content === 'string') { - return options.content - } - else if (isVNode(options.content)) { - return options.content - } - else if (options.content) { - return h(options.content) - } - return null - }, - }) - }, - }) - // 继承主应用的上下文 const instance = getCurrentInstance() - if (instance && instance.appContext) { - Object.assign(app._context, instance.appContext) + let vnode: VNode | null = null + + const updateVNode = () => { + vnode = createVNode(Drawer, Object.assign({ + 'id': instance && instance.uid ? `FaDrawer-${instance.uid}` : undefined, + 'modelValue': visible.value, + 'onUpdate:modelValue': (val: boolean) => { + visible.value = val + }, + ...options, + }), { + default: () => { + if (typeof options.content === 'string') { + return options.content + } + else if (isVNode(options.content)) { + return options.content + } + else if (options.content) { + return h(options.content) + } + return null + }, + }) + // 继承主应用的上下文 + if (instance && instance.appContext) { + vnode.appContext = instance.appContext + } + render(vnode, container) } - app.mount(container) + + // 监听 visible 和 options 变化,自动重新渲染 + watch([visible, options], () => { + updateVNode() + }, { + immediate: true, + deep: true, + }) + + // 挂载到当前实例 + instance?.proxy?.$el?.appendChild(container) + const open = () => { visible.value = true } diff --git a/src/ui/components/FaModal/index.ts b/src/ui/components/FaModal/index.ts index 66ff8118..a662cf87 100644 --- a/src/ui/components/FaModal/index.ts +++ b/src/ui/components/FaModal/index.ts @@ -1,5 +1,5 @@ import type { Component, HTMLAttributes } from 'vue' -import { isVNode } from 'vue' +import { createVNode, isVNode, render } from 'vue' import Modal from './index.vue' export interface ModalProps { @@ -67,36 +67,49 @@ export function useFaModal() { const container = document.createElement('div') const visible = ref(false) const options = reactive({ ...initialOptions }) - const app = createApp({ - render() { - return h(Modal, Object.assign({ - 'id': useId(), - 'modelValue': visible.value, - 'onUpdate:modelValue': (val: boolean) => { - visible.value = val - }, - }, options), { - default: () => { - if (typeof options.content === 'string') { - return options.content - } - else if (isVNode(options.content)) { - return options.content - } - else if (options.content) { - return h(options.content) - } - return null - }, - }) - }, - }) - // 继承主应用的上下文 const instance = getCurrentInstance() - if (instance && instance.appContext) { - Object.assign(app._context, instance.appContext) + let vnode: VNode | null = null + + const updateVNode = () => { + vnode = createVNode(Modal, Object.assign({ + 'id': instance && instance.uid ? `FaModal-${instance.uid}` : undefined, + 'modelValue': visible.value, + 'onUpdate:modelValue': (val: boolean) => { + visible.value = val + }, + ...options, + }), { + default: () => { + if (typeof options.content === 'string') { + return options.content + } + else if (isVNode(options.content)) { + return options.content + } + else if (options.content) { + return h(options.content) + } + return null + }, + }) + // 继承主应用的上下文 + if (instance && instance.appContext) { + vnode.appContext = instance.appContext + } + render(vnode, container) } - app.mount(container) + + // 监听 visible 和 options 变化,自动重新渲染 + watch([visible, options], () => { + updateVNode() + }, { + immediate: true, + deep: true, + }) + + // 挂载到当前实例 + instance?.proxy?.$el?.appendChild(container) + const open = () => { visible.value = true } @@ -179,8 +192,11 @@ export function useFaModal() { contentClass: 'py-0 min-h-auto', footerClass: 'p-4', } - const { open } = create(Object.assign(defaultOptions, options)) + const { open, update } = create(Object.assign(defaultOptions, options)) open() + return { + update, + } } return { create,