From d390daeeadcfd404b0e052378cc78d5897622cd1 Mon Sep 17 00:00:00 2001 From: Hooray <304327508@qq.com> Date: Tue, 22 Jul 2025 18:36:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20`FaModal`=20=E5=92=8C=20`FaDrawer`=20?= =?UTF-8?q?=E5=88=86=E5=88=AB=E5=A2=9E=E5=8A=A0=E5=91=BD=E4=BB=A4=E5=BC=8F?= =?UTF-8?q?=E8=B0=83=E7=94=A8API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/ui/components/FaDrawer/index.ts | 110 +++++++++ src/ui/components/FaDrawer/index.vue | 122 +++++----- .../FaDrawer/sheet/SheetContent.vue | 5 +- src/ui/components/FaModal/index.ts | 213 ++++++++++-------- src/ui/components/FaModal/index.vue | 20 +- 5 files changed, 305 insertions(+), 165 deletions(-) create mode 100644 src/ui/components/FaDrawer/index.ts diff --git a/src/ui/components/FaDrawer/index.ts b/src/ui/components/FaDrawer/index.ts new file mode 100644 index 00000000..58d33762 --- /dev/null +++ b/src/ui/components/FaDrawer/index.ts @@ -0,0 +1,110 @@ +import type { Component, HTMLAttributes } from 'vue' +import { isVNode } from 'vue' +import Drawer from './index.vue' + +export interface DrawerProps { + id?: string + modelValue?: boolean + side?: 'top' | 'bottom' | 'left' | 'right' + title?: string + description?: string + loading?: boolean + closable?: boolean + centered?: boolean + bordered?: boolean + overlay?: boolean + overlayBlur?: boolean + showConfirmButton?: boolean + showCancelButton?: boolean + confirmButtonText?: string + cancelButtonText?: string + confirmButtonDisabled?: boolean + confirmButtonLoading?: boolean + beforeClose?: ( + action: 'confirm' | 'cancel' | 'close', + done: () => void + ) => void + header?: boolean + footer?: boolean + closeOnClickOverlay?: boolean + closeOnPressEscape?: boolean + destroyOnClose?: boolean + contentClass?: HTMLAttributes['class'] + headerClass?: HTMLAttributes['class'] + footerClass?: HTMLAttributes['class'] +} + +export interface DrawerEmits { + 'update:modelValue': [value: boolean] + 'open': [] + 'opened': [] + 'close': [] + 'closed': [] + 'confirm': [] + 'cancel': [] +} + +type BaseOptions = Omit & { + content?: Component | VNode | string + onOpen?: () => void + onOpened?: () => void + onClose?: () => void + onClosed?: () => void + onConfirm?: () => void + onCancel?: () => void +} + +export function useFaDrawer() { + function create(initialOptions: BaseOptions) { + 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) + } + app.mount(container) + const open = () => { + visible.value = true + } + const close = () => { + visible.value = false + } + const update = (newOptions: BaseOptions) => { + Object.assign(options, newOptions) + } + return { + open, + close, + update, + } + } + return { + create, + } +} diff --git a/src/ui/components/FaDrawer/index.vue b/src/ui/components/FaDrawer/index.vue index ad382b64..e54adbe6 100644 --- a/src/ui/components/FaDrawer/index.vue +++ b/src/ui/components/FaDrawer/index.vue @@ -1,5 +1,5 @@