diff --git a/packages/devui-vue/devui/drawer/src/components/drawer-body.tsx b/packages/devui-vue/devui/drawer/src/components/drawer-body.tsx index d3525a420f..6fba8f93e9 100644 --- a/packages/devui-vue/devui/drawer/src/components/drawer-body.tsx +++ b/packages/devui-vue/devui/drawer/src/components/drawer-body.tsx @@ -1,4 +1,4 @@ -import { defineComponent, inject, computed } from 'vue' +import { defineComponent, inject, computed, Transition } from 'vue' import './drawer-body.scss' @@ -14,6 +14,7 @@ export default defineComponent({ const visible: boolean = inject('visible') const backdropCloseable: any = inject('backdropCloseable') const destroyOnHide: any = inject('destroyOnHide') + const showAnimation: any = inject('showAnimation') const navRight = computed(() => position.value === 'right' ? { 'right': 0 } : { 'left': 0 }) const navWidth = computed(() => isFullScreen.value ? '100vw' : width.value) @@ -34,6 +35,8 @@ export default defineComponent({ navRight, navWidth, visible, + position, + showAnimation, clickContent, handleDrawerClose, destroyOnHide, @@ -42,25 +45,27 @@ export default defineComponent({ render() { const { - zindex, slots, isCover, navRight, navWidth, - visible, handleDrawerClose, destroyOnHide } = this + zindex, slots, isCover, navRight, navWidth, showAnimation, + visible, handleDrawerClose, destroyOnHide, position } = this if (destroyOnHide.value && !visible) { return null } - const visibleVal = visible ? 'visible' : 'hidden' + const transitionName = showAnimation ? position : 'none' return ( -
+
{isCover ?
: null} -
-
-
- {slots.default ? slots.default() : null} + +
+
+
+ {slots.default ? slots.default() : null} +
-
+
) } diff --git a/packages/devui-vue/devui/drawer/src/components/drawer-container.tsx b/packages/devui-vue/devui/drawer/src/components/drawer-container.tsx index b52256240e..f348d456e2 100644 --- a/packages/devui-vue/devui/drawer/src/components/drawer-container.tsx +++ b/packages/devui-vue/devui/drawer/src/components/drawer-container.tsx @@ -13,7 +13,6 @@ export default defineComponent({ if (destroyOnHide.value && !visible) { return null } - const visibleVal = this.visible ? 'visible' : 'hidden' - return
内容区域
+ return
内容区域
} }) \ No newline at end of file diff --git a/packages/devui-vue/devui/drawer/src/components/drawer-header.tsx b/packages/devui-vue/devui/drawer/src/components/drawer-header.tsx index 13ed5062e0..9adbe932db 100644 --- a/packages/devui-vue/devui/drawer/src/components/drawer-header.tsx +++ b/packages/devui-vue/devui/drawer/src/components/drawer-header.tsx @@ -26,19 +26,17 @@ export default defineComponent({ return { fullScreenClassName, visible, handleFullScreen, handleDrawerClose, destroyOnHide } }, render() { - const { - handleFullScreen, handleDrawerClose, visible, - fullScreenClassName, destroyOnHide + const { + handleFullScreen, handleDrawerClose, visible, + fullScreenClassName, destroyOnHide } = this if (destroyOnHide.value && !visible) { return null } - const visibleVal = visible ? 'visible' : 'hidden' - return ( -
+
diff --git a/packages/devui-vue/devui/drawer/src/drawer-service.tsx b/packages/devui-vue/devui/drawer/src/drawer-service.tsx index 237a0fc8a6..ffb7f2a811 100644 --- a/packages/devui-vue/devui/drawer/src/drawer-service.tsx +++ b/packages/devui-vue/devui/drawer/src/drawer-service.tsx @@ -2,6 +2,7 @@ import { createApp } from 'vue' import { DrawerProps } from './drawer-types' import DDrawer from './drawer' +import { omit } from 'lodash-es' interface drawerInstance { hide(): void @@ -13,8 +14,12 @@ function createDrawerApp(props: DrawerProps, drawer: drawerInstance, el: HTMLEle if (drawer) { return drawer } + const restProps = omit(props, ['header', 'content', 'visible']) + const res = createApp( - {{ header: props.header, content: props.content }} + // BUG: this function generates a new app, v-model instructor of template is like not working + // TODO: could be fixed by using self-defined header slot + {{ header: props.header, content: props.content }} ) res.mount(el) return res diff --git a/packages/devui-vue/devui/drawer/src/drawer-types.ts b/packages/devui-vue/devui/drawer/src/drawer-types.ts index 149cc22cba..6ff7e1f959 100644 --- a/packages/devui-vue/devui/drawer/src/drawer-types.ts +++ b/packages/devui-vue/devui/drawer/src/drawer-types.ts @@ -33,14 +33,18 @@ export const drawerProps = { type: Boolean, default: false, }, + showAnimation: { // 是否启用动效 + type: Boolean, + default: true, + }, beforeHidden: { // 关闭前的回调 type: [Promise, Function] as PropType | (() => boolean | Promise)>, }, content: { // 默认内容插槽 - type: [Object, Function], + type: Object, }, header: { // 头部内容插槽 - type: [Object, Function], + type: Object, }, } as const diff --git a/packages/devui-vue/devui/drawer/src/drawer.scss b/packages/devui-vue/devui/drawer/src/drawer.scss index 8b13789179..49caf1ee62 100644 --- a/packages/devui-vue/devui/drawer/src/drawer.scss +++ b/packages/devui-vue/devui/drawer/src/drawer.scss @@ -1 +1,41 @@ +.devui-drawer{ + &-left-enter-active { + animation: left-inout 0.3s; + } + &-left-leave-active { + animation: left-inout 0.3s reverse; + } + + &-right-enter-active { + animation: right-inout 0.3s; + } + + &-right-leave-active { + animation: right-inout 0.3s reverse; + } +} + +@keyframes right-inout { + 0% { + transform: translateX(100px); + opacity: 0; + } + + 100% { + transform: translateX(0); + opacity: 1; + } +} + +@keyframes left-inout { + 0% { + transform: translateX(-100px); + opacity: 0; + } + + 100% { + transform: translateX(0); + opacity: 1; + } +} \ No newline at end of file diff --git a/packages/devui-vue/devui/drawer/src/drawer.tsx b/packages/devui-vue/devui/drawer/src/drawer.tsx index 9701947cfc..9bde30a3d5 100644 --- a/packages/devui-vue/devui/drawer/src/drawer.tsx +++ b/packages/devui-vue/devui/drawer/src/drawer.tsx @@ -5,6 +5,8 @@ import DrawerHeader from './components/drawer-header' import DrawerContainer from './components/drawer-container' import DrawerBody from './components/drawer-body' +import './drawer.scss' + export default defineComponent({ name: 'DDrawer', props: drawerProps, @@ -12,10 +14,10 @@ export default defineComponent({ setup(props: DrawerProps, { emit, slots }) { const { width, visible, zIndex, isCover, escKeyCloseable, position, - backdropCloseable, destroyOnHide + backdropCloseable, destroyOnHide, showAnimation } = toRefs(props) const isFullScreen = ref(false) - + const fullscreen = () => { isFullScreen.value = !isFullScreen.value } @@ -66,6 +68,7 @@ export default defineComponent({ provide('isFullScreen', isFullScreen) provide('backdropCloseable', backdropCloseable) provide('destroyOnHide', destroyOnHide) + provide('showAnimation', showAnimation) onUnmounted(() => { document.removeEventListener('keyup', escCloseDrawer) @@ -81,16 +84,15 @@ export default defineComponent({ }, render() { const { fullscreen, closeDrawer, visible, destroyOnHide } = this; + if (destroyOnHide.value && !visible) { return null } - const visibleVal = visible ? 'visible' : 'hidden' return ( - - {/* BUG: 已使用作用域插槽解决 此处对应的 DEMO 使用了 **双向绑定** 导致可以关闭【一种关闭了的'假象'】。*/} - {this.slots.header ? this.slots.header({fullscreen, closeDrawer}) : + + {this.slots.header ? this.slots.header({fullscreen, closeDrawer}) : } {this.slots.content ? this.slots.content() : } diff --git a/packages/devui-vue/docs/components/drawer/index.md b/packages/devui-vue/docs/components/drawer/index.md index daee278cdb..b1aaa8b68e 100644 --- a/packages/devui-vue/docs/components/drawer/index.md +++ b/packages/devui-vue/docs/components/drawer/index.md @@ -29,34 +29,34 @@ /> ``` @@ -97,22 +97,22 @@ export default { ``` @@ -127,42 +127,41 @@ export default { click me ``` @@ -208,6 +207,7 @@ export default defineComponent({ | beforeHidden | `Function \| Promise` | -- | 可选,关闭窗口之前的回调 | [基本用法](#基本用法) | | onClose | `Function` | -- | 可选,关闭 drawer 时候调用 | [基本用法](#基本用法) | | onAfterOpened | `Function` | -- | 可选,打开 drawer 后时候调用 | [基本用法](#基本用法) | +| showAnimation | `boolean` | true | 可选,是否开启动效 | [基本用法](#基本用法) | ### 插槽