重构 useFaModal 和 useFaDrawer

This commit is contained in:
Hooray
2025-07-29 00:57:27 +08:00
parent 59fb213060
commit 522a97f8d6
3 changed files with 118 additions and 60 deletions
+42 -29
View File
@@ -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
}
+46 -30
View File
@@ -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,
+30 -1
View File
@@ -87,7 +87,33 @@ function showModalConfirm() {
},
})
}
function showModalDoubleConfirm() {
const { update } = useFaModal().confirm({
title: '温馨提醒',
content: '这是 confirm 弹窗',
beforeClose: (action, done) => {
if (action === 'confirm') {
update({
title: '二次确认',
content: '确定要关闭吗?',
confirmButtonText: '我确定',
cancelButtonText: '我取消',
beforeClose: (action) => {
if (action === 'confirm') {
done()
}
else {
done()
}
},
})
}
else {
done()
}
},
})
}
function showModalPromiseConfirm() {
useFaModal().confirm({
title: '温馨提醒',
@@ -201,6 +227,9 @@ const { open: open2 } = useFaModal().create({
<FaButton @click="showModalConfirm">
Confirm
</FaButton>
<FaButton @click="showModalDoubleConfirm">
Double Confirm
</FaButton>
<FaButton @click="showModalPromiseConfirm">
Confirm with promise
</FaButton>