diff --git a/packages/devui-vue/devui/drawer/src/drawer-service.ts b/packages/devui-vue/devui/drawer/src/drawer-service.ts deleted file mode 100644 index df635e6aae..0000000000 --- a/packages/devui-vue/devui/drawer/src/drawer-service.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { createApp } from 'vue' -import { DrawerProps } from './drawer-types' -import Drawer from './drawer' -import { inBrowser } from '../../shared/util/common-var' - -function createDrawerApp(props: DrawerProps) { - return createApp(Drawer, { ...props }) -} - -export default class DrawerService { - - static $body: HTMLElement | null - static $div: HTMLDivElement | null = null - static drawer = null; - - static show(props: DrawerProps): void{ - this.$div = document.createElement('div') - this.$body.appendChild(this.$div) - this.drawer = createDrawerApp(props) - this.drawer.mount(this.$div) - } - - static hide(): void { - this.drawer?.unmount(); - this.drawer = null; - if (this.$div) { - this.$body.removeChild(this.$div) - } - this.$div = null - } -} - -if (inBrowser) { - DrawerService.$body = document.body -} diff --git a/packages/devui-vue/devui/drawer/src/drawer-service.tsx b/packages/devui-vue/devui/drawer/src/drawer-service.tsx new file mode 100644 index 0000000000..645f62d74c --- /dev/null +++ b/packages/devui-vue/devui/drawer/src/drawer-service.tsx @@ -0,0 +1,66 @@ +import { createApp } from 'vue' +import { DrawerProps } from './drawer-types' + +import DDrawer from './drawer' + +interface drawerInstance { + hide(): void + hideDirectly(): void + destroy(): void +} + +function createDrawerApp(props: DrawerProps, drawer: drawerInstance, el: HTMLElement) { + if (drawer) { + return drawer + } + const res = createApp( + {{ header: props.header, content: props.content }} + ) + res.mount(el) + return res +} + +export default class DrawerService { + static create(props: DrawerProps, drawer: drawerInstance): drawerInstance { + if (!drawer) { + drawer = new Drawer(props) + } + return drawer + } +} + +class Drawer { + private drawer: any = null + private div: HTMLElement = null + private props: DrawerProps = null + + constructor(props: DrawerProps) { + this.props = props + } + + public show(): void { + this.div = document.createElement('div') + this.drawer = createDrawerApp(this.props, this.drawer, this.div) + this.drawer._instance.props.visible = true + } + + public hide = async (): Promise => { + const beforeHidden = this.props.beforeHidden + let result = (typeof beforeHidden === 'function' ? beforeHidden() : beforeHidden) ?? false + if (result instanceof Promise) { + result = await result + } + if (!result) this.hideDirectly() + } + + public hideDirectly = (): void => { + this.drawer._instance.props.visible = false + this.div.remove() + } + + public destroy = (): void => { + this.drawer.unmount() + this.drawer = null + this.div.remove() + } +} diff --git a/packages/devui-vue/devui/drawer/src/drawer-types.ts b/packages/devui-vue/devui/drawer/src/drawer-types.ts index 207cf89ef5..3be23c4aea 100644 --- a/packages/devui-vue/devui/drawer/src/drawer-types.ts +++ b/packages/devui-vue/devui/drawer/src/drawer-types.ts @@ -1,37 +1,43 @@ import type { ExtractPropTypes, PropType } from 'vue' export const drawerProps = { - width: { + width: { // 宽度 type: String, default: '300px', }, - visible: { + visible: { // 是否可见 type: Boolean, default: false, }, - zIndex: { + zIndex: { // 层级 type: Number, default: 1000, }, - isCover: { + isCover: { // 是否有遮罩层 type: Boolean, default: true, }, - escKeyCloseable: { + escKeyCloseable: { // 是否可通过esc关闭 type: Boolean, default: true, }, - position: { + position: { // 位置 只有左和右 type: String as PropType<'left' | 'right'>, default: 'left', }, - backdropCloseable: { + backdropCloseable: { // 点击遮罩层是否可关闭 type: Boolean, default: true, }, - beforeHidden: { + beforeHidden: { // 关闭前的回调 type: [Promise, Function] as PropType | (() => boolean | Promise)>, }, + content: { // 默认内容插槽 + type: [Object, Function], + }, + header: { // 头部内容插槽 + type: [Object, Function], + }, } as const export type DrawerProps = ExtractPropTypes diff --git a/packages/devui-vue/devui/drawer/src/drawer.tsx b/packages/devui-vue/devui/drawer/src/drawer.tsx index 418fe5f30a..7e2d076dcd 100644 --- a/packages/devui-vue/devui/drawer/src/drawer.tsx +++ b/packages/devui-vue/devui/drawer/src/drawer.tsx @@ -5,8 +5,6 @@ import DrawerHeader from './components/drawer-header' import DrawerContainer from './components/drawer-container' import DrawerBody from './components/drawer-body' -import DrawerService from './drawer-service'; - export default defineComponent({ name: 'DDrawer', props: drawerProps, @@ -18,12 +16,11 @@ export default defineComponent({ } = toRefs(props) const isFullScreen = ref(false) - const fullScreenEvent = () => { + const fullscreen = () => { isFullScreen.value = !isFullScreen.value } const closeDrawer = async () => { - DrawerService.hide() const beforeHidden = props.beforeHidden; let result = (typeof beforeHidden === 'function' ? beforeHidden(): beforeHidden) ?? false; if (result instanceof Promise) { @@ -31,6 +28,7 @@ export default defineComponent({ } if (result) return; + // BUG: 以服务方式 此处不生效 emit('update:visible', false) emit('close') } @@ -70,12 +68,12 @@ export default defineComponent({ isFullScreen, visible, slots, - fullScreenEvent, + fullscreen, closeDrawer, } }, render() { - const fullScreenEvent: any = this.fullScreenEvent + const fullscreen: any = this.fullscreen const closeDrawer: any = this.closeDrawer if (!this.visible) return null @@ -83,10 +81,11 @@ export default defineComponent({ return ( - {this.slots.header ? this.slots.header() : - + {/* BUG: 已使用作用域插槽解决 此处对应的 DEMO 使用了 **双向绑定** 导致可以关闭【一种关闭了的'假象'】。*/} + {this.slots.header ? this.slots.header({fullscreen, closeDrawer}) : + } - {this.slots.default ? this.slots.default() : } + {this.slots.content ? this.slots.content() : } )