-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
1,104 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { ref } from "vue"; | ||
import reDrawer from "./index.vue"; | ||
import { useTimeoutFn } from "@vueuse/core"; | ||
import { withInstall } from "@pureadmin/utils"; | ||
import type { | ||
EventType, | ||
ArgsType, | ||
DrawerProps, | ||
DrawerOptions, | ||
ButtonProps | ||
} from "./type"; | ||
|
||
const drawerStore = ref<Array<DrawerOptions>>([]); | ||
|
||
/** 打开抽屉 */ | ||
const addDrawer = (options: DrawerOptions) => { | ||
const open = () => | ||
drawerStore.value.push(Object.assign(options, { visible: true })); | ||
if (options?.openDelay) { | ||
useTimeoutFn(() => { | ||
open(); | ||
}, options.openDelay); | ||
} else { | ||
open(); | ||
} | ||
}; | ||
|
||
/** 关闭抽屉 */ | ||
const closeDrawer = (options: DrawerOptions, index: number, args?: any) => { | ||
drawerStore.value[index].visible = false; | ||
options.closeCallBack && options.closeCallBack({ options, index, args }); | ||
|
||
const closeDelay = options?.closeDelay ?? 200; | ||
useTimeoutFn(() => { | ||
drawerStore.value.splice(index, 1); | ||
}, closeDelay); | ||
}; | ||
|
||
/** | ||
* @description 更改抽屉自身属性值 | ||
* @param value 属性值 | ||
* @param key 属性,默认`title` | ||
* @param index 弹框索引(默认`0`,代表只有一个弹框,对于嵌套弹框要改哪个弹框的属性值就把该弹框索引赋给`index`) | ||
*/ | ||
const updateDrawer = (value: any, key = "title", index = 0) => { | ||
drawerStore.value[index][key] = value; | ||
}; | ||
|
||
/** 关闭所有弹框 */ | ||
const closeAllDrawer = () => { | ||
drawerStore.value = []; | ||
}; | ||
|
||
const ReDrawer = withInstall(reDrawer); | ||
|
||
export type { EventType, ArgsType, DrawerOptions, DrawerProps, ButtonProps }; | ||
export { | ||
ReDrawer, | ||
drawerStore, | ||
addDrawer, | ||
closeDrawer, | ||
updateDrawer, | ||
closeAllDrawer | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
<script setup lang="ts"> | ||
import { | ||
type EventType, | ||
type ButtonProps, | ||
type DrawerOptions, | ||
closeDrawer, | ||
drawerStore | ||
} from "./index"; | ||
import { computed, ref } from "vue"; | ||
import { isFunction } from "@pureadmin/utils"; | ||
defineOptions({ | ||
name: "ReDrawer" | ||
}); | ||
const sureBtnMap = ref({}); | ||
const footerButtons = computed(() => { | ||
return (options: DrawerOptions) => { | ||
return options?.footerButtons?.length > 0 | ||
? options.footerButtons | ||
: ([ | ||
{ | ||
label: "取消", | ||
text: true, | ||
bg: true, | ||
btnClick: ({ drawer: { options, index } }) => { | ||
const done = () => | ||
closeDrawer(options, index, { command: "cancel" }); | ||
if (options?.beforeCancel && isFunction(options?.beforeCancel)) { | ||
options.beforeCancel(done, { options, index }); | ||
} else { | ||
done(); | ||
} | ||
} | ||
}, | ||
{ | ||
label: "确定", | ||
type: "primary", | ||
text: true, | ||
bg: true, | ||
popConfirm: options?.popConfirm, | ||
btnClick: ({ drawer: { options, index } }) => { | ||
if (options?.sureBtnLoading) { | ||
sureBtnMap.value[index] = Object.assign( | ||
{}, | ||
sureBtnMap.value[index], | ||
{ | ||
loading: true | ||
} | ||
); | ||
} | ||
const closeLoading = () => { | ||
if (options?.sureBtnLoading) { | ||
sureBtnMap.value[index].loading = false; | ||
} | ||
}; | ||
const done = () => { | ||
closeLoading(); | ||
closeDrawer(options, index, { command: "sure" }); | ||
}; | ||
if (options?.beforeSure && isFunction(options?.beforeSure)) { | ||
options.beforeSure(done, { options, index, closeLoading }); | ||
} else { | ||
done(); | ||
} | ||
} | ||
} | ||
] as Array<ButtonProps>); | ||
}; | ||
}); | ||
function eventsCallBack( | ||
event: EventType, | ||
options: DrawerOptions, | ||
index: number | ||
) { | ||
if (options?.[event] && isFunction(options?.[event])) { | ||
return options?.[event]({ options, index }); | ||
} | ||
} | ||
/** | ||
* | ||
* @param {DrawerOptions} options - 包含抽屉相关配置的对象 | ||
* @param {number} index - 抽屉的索引 | ||
* @param {Object} args - 传递给关闭抽屉操作的参数对象,默认为 { command: 'close' } | ||
* @returns {void} 这个函数不返回任何值 | ||
*/ | ||
function handleClose( | ||
options: DrawerOptions, | ||
index: number, | ||
args = { command: "close" } | ||
) { | ||
closeDrawer(options, index, args); | ||
eventsCallBack("close", options, index); | ||
} | ||
</script> | ||
|
||
<template> | ||
<el-drawer | ||
v-for="(options, index) in drawerStore" | ||
:key="index" | ||
v-bind="options" | ||
v-model="options.visible" | ||
class="pure-drawer" | ||
:append-to-body="!!options?.appendToBody" | ||
:append-to="options?.appendTo ? options.appendTo : 'body'" | ||
:destroy-on-close="!!options?.destroyOnClose" | ||
:lock-scroll="!!options?.lockScroll" | ||
@closed="handleClose(options, index)" | ||
@opened="eventsCallBack('open', options, index)" | ||
@open-auto-focus="eventsCallBack('openAutoFocus', options, index)" | ||
@close-auto-focus="eventsCallBack('closeAutoFocus', options, index)" | ||
> | ||
<!-- header --> | ||
<template | ||
v-if="options?.headerRenderer" | ||
#header="{ close, titleId, titleClass }" | ||
> | ||
<component | ||
:is="options?.headerRenderer({ close, titleId, titleClass })" | ||
/> | ||
</template> | ||
<!-- body --> | ||
<component | ||
v-bind="options?.props" | ||
:is="options.contentRenderer({ options, index })" | ||
@close="args => handleClose(options, index, args)" | ||
/> | ||
<!-- footer --> | ||
<template v-if="!options?.hideFooter" #footer> | ||
<template v-if="options?.footerRenderer"> | ||
<component :is="options?.footerRenderer({ options, index })" /> | ||
</template> | ||
<span v-else> | ||
<template v-for="(btn, key) in footerButtons(options)" :key="key"> | ||
<el-popconfirm | ||
v-if="btn.popConfirm" | ||
v-bind="btn.popConfirm" | ||
@confirm=" | ||
btn.btnClick({ | ||
drawer: { options, index }, | ||
button: { btn, index: key } | ||
}) | ||
" | ||
> | ||
<template #reference> | ||
<el-button v-bind="btn">{{ btn?.label }}</el-button> | ||
</template> | ||
</el-popconfirm> | ||
<el-button | ||
v-else | ||
v-bind="btn" | ||
:loading="key === 1 && sureBtnMap[index]?.loading" | ||
@click=" | ||
btn.btnClick({ | ||
drawer: { options, index }, | ||
button: { btn, index: key } | ||
}) | ||
" | ||
> | ||
{{ btn?.label }} | ||
</el-button> | ||
</template> | ||
</span> | ||
</template> | ||
</el-drawer> | ||
</template> |
Oops, something went wrong.