From 5032a7522181864dd6687d83ac40168705311fa7 Mon Sep 17 00:00:00 2001 From: Mer <276557421@qq.com> Date: Wed, 25 Sep 2024 16:49:12 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E5=BC=8F=E6=8A=BD=E5=B1=89=E7=BB=84=E4=BB=B6=20(#1183?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 函数式抽屉组件 * feat: 添加ReDrawer demo * fix: 组件ReDrawer 增加按钮loading等功能 --- locales/en.yaml | 1 + locales/zh-CN.yaml | 3 +- src/App.vue | 5 +- src/components/ReDrawer/index.ts | 64 +++ src/components/ReDrawer/index.vue | 169 ++++++ src/components/ReDrawer/type.ts | 262 +++++++++ src/router/modules/components.ts | 8 + src/views/components/dialog/index.vue | 6 +- src/views/components/drawer/form.vue | 47 ++ src/views/components/drawer/formPrimitive.vue | 22 + src/views/components/drawer/index.vue | 502 ++++++++++++++++++ 11 files changed, 1084 insertions(+), 5 deletions(-) create mode 100644 src/components/ReDrawer/index.ts create mode 100644 src/components/ReDrawer/index.vue create mode 100644 src/components/ReDrawer/type.ts create mode 100644 src/views/components/drawer/form.vue create mode 100644 src/views/components/drawer/formPrimitive.vue create mode 100644 src/views/components/drawer/index.vue diff --git a/locales/en.yaml b/locales/en.yaml index 3793277b12..2aa5a24cf5 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -83,6 +83,7 @@ menus: pureFive: "500" pureComponents: Components pureDialog: Dialog + pureDrawer: Drawer pureMessage: Message Tips pureVideo: Video pureSegmented: Segmented diff --git a/locales/zh-CN.yaml b/locales/zh-CN.yaml index 7be27a8ecf..0287a09558 100644 --- a/locales/zh-CN.yaml +++ b/locales/zh-CN.yaml @@ -83,6 +83,7 @@ menus: pureFive: "500" pureComponents: 组件 pureDialog: 函数式弹框 + pureDrawer: 函数式抽屉 pureMessage: 消息提示 pureVideo: 视频 pureSegmented: 分段控制器 @@ -233,4 +234,4 @@ login: purePassWordRuleReg: 密码格式应为8-18位数字、字母、符号的任意两种组合 purePassWordSureReg: 请输入确认密码 purePassWordDifferentReg: 两次密码不一致! - purePassWordUpdateReg: 修改密码成功 + purePassWordUpdateReg: 修改密码成功 \ No newline at end of file diff --git a/src/App.vue b/src/App.vue index 1a8766c3a6..a1d0c8b22c 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,6 +2,7 @@ + @@ -10,6 +11,7 @@ import { defineComponent } from "vue"; import { checkVersion } from "version-rocket"; import { ElConfigProvider } from "element-plus"; import { ReDialog } from "@/components/ReDialog"; +import { ReDrawer } from "@/components/ReDrawer"; import en from "element-plus/es/locale/lang/en"; import zhCn from "element-plus/es/locale/lang/zh-cn"; import plusEn from "plus-pro-components/es/locale/lang/en"; @@ -19,7 +21,8 @@ export default defineComponent({ name: "app", components: { [ElConfigProvider.name]: ElConfigProvider, - ReDialog + ReDialog, + ReDrawer }, computed: { currentLocale() { diff --git a/src/components/ReDrawer/index.ts b/src/components/ReDrawer/index.ts new file mode 100644 index 0000000000..36d6cb0d0c --- /dev/null +++ b/src/components/ReDrawer/index.ts @@ -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>([]); + +/** 打开抽屉 */ +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 +}; diff --git a/src/components/ReDrawer/index.vue b/src/components/ReDrawer/index.vue new file mode 100644 index 0000000000..d5280c5d5c --- /dev/null +++ b/src/components/ReDrawer/index.vue @@ -0,0 +1,169 @@ + + + diff --git a/src/components/ReDrawer/type.ts b/src/components/ReDrawer/type.ts new file mode 100644 index 0000000000..b2eaeb9695 --- /dev/null +++ b/src/components/ReDrawer/type.ts @@ -0,0 +1,262 @@ +import type { CSSProperties, VNode, Component } from "vue"; + +type DoneFn = (cancel?: boolean) => void; +type EventType = "open" | "close" | "openAutoFocus" | "closeAutoFocus"; +type ArgsType = { + /** `cancel` 点击取消按钮、`sure` 点击确定按钮、`close` 点击右上角关闭按钮或空白页或按下了 `esc` 键 */ + command: "cancel" | "sure" | "close"; +}; + +type ButtonType = + | "primary" + | "success" + | "warning" + | "danger" + | "info" + | "text"; + +type DrawerProps = { + /** `Drawer` 的显示与隐藏 */ + visible?: boolean; + /** `Drawer` 自身是否插入至 `body` 元素上。嵌套的 `Drawer` 必须指定该属性并赋值为 `true`,默认 `false` */ + appendToBody?: boolean; + /** 挂载到哪个 `DOM` 元素 将覆盖 `appendToBody` */ + appendTo?: string; + /** 是否在 `Drawer` 出现时将 `body` 滚动锁定,默认 `true` */ + lockScroll?: boolean; + /** 关闭前的回调,会暂停 `Drawer` 的关闭 回调函数内执行 `done` 参数方法的时候才是真正关闭对话框的时候 */ + beforeClose?: (done: DoneFn) => void; + /** 是否可以通过点击 `modal` 关闭 `Drawer` ,默认 `true` */ + closeOnClickModal?: boolean; + /** 是否可以通过按下 `ESC` 关闭 `Drawer` ,默认 `true` */ + closeOnPressEscape?: boolean; + /** 是否显示关闭按钮,默认 `true` */ + showClose?: boolean; + /** `Drawer` 打开的延时时间,单位毫秒,默认 `0` */ + openDelay?: number; + /** `Drawer` 关闭的延时时间,单位毫秒,默认 `0` */ + closeDelay?: number; + /** `Drawer` 自定义类名 */ + class?: string; + /** `Drawer` 的自定义样式 */ + style?: CSSProperties; + /** 控制是否在关闭 `Drawer` 之后将子元素全部销毁,默认 `false` */ + destroyOnClose?: boolean; + /** 是否需要遮罩层,默认 `true` */ + modal?: boolean; + /** `Drawer` 打开的方向,默认 `rtl` */ + direction?: "rtl" | "ltr" | "ttb" | "btt"; + /** `Drawer` 窗体的大小, 当使用 `number` 类型时, 以像素为单位, 当使用 `string` 类型时, 请传入 `'x%'`, 否则便会以 `number` 类型解释 */ + size?: string | number; + /** `Drawer` 的标题 */ + title?: string; + /** 控制是否显示 `header` 栏, 默认为 `true`, 当此项为 `false` 时, `title attribute` 和 `title slot` 均不生效 */ + withHeader?: boolean; + /** 遮罩层的自定义类名 */ + modalClass?: string; + /** 设置 `z-index` */ + zIndex?: number; + /** `header` 的 `aria-level` 属性,默认 `2` */ + headerAriaLevel?: string; +}; + +//element-plus.org/zh-CN/component/popConfirm.html#attributes +type PopConfirm = { + /** 标题 */ + title?: string; + /** 确认按钮文字 */ + confirmButtonText?: string; + /** 取消按钮文字 */ + cancelButtonText?: string; + /** 确认按钮类型,默认 `primary` */ + confirmButtonType?: ButtonType; + /** 取消按钮类型,默认 `text` */ + cancelButtonType?: ButtonType; + /** 自定义图标,默认 `QuestionFilled` */ + icon?: string | Component; + /** `Icon` 颜色,默认 `#f90` */ + iconColor?: string; + /** 是否隐藏 `Icon`,默认 `false` */ + hideIcon?: boolean; + /** 关闭时的延迟,默认 `200` */ + hideAfter?: number; + /** 是否将 `popover` 的下拉列表插入至 `body` 元素,默认 `true` */ + teleported?: boolean; + /** 当 `popover` 组件长时间不触发且 `persistent` 属性设置为 `false` 时, `popover` 将会被删除,默认 `false` */ + persistent?: boolean; + /** 弹层宽度,最小宽度 `150px`,默认 `150` */ + width?: string | number; +}; + +type BtnClickDrawer = { + options?: DrawerOptions; + index?: number; +}; +type BtnClickButton = { + btn?: ButtonProps; + index?: number; +}; +/** https://element-plus.org/zh-CN/component/button.html#button-attributes */ +type ButtonProps = { + /** 按钮文字 */ + label: string; + /** 按钮尺寸 */ + size?: "large" | "default" | "small"; + /** 按钮类型 */ + type?: "primary" | "success" | "warning" | "danger" | "info"; + /** 是否为朴素按钮,默认 `false` */ + plain?: boolean; + /** 是否为文字按钮,默认 `false` */ + text?: boolean; + /** 是否显示文字按钮背景颜色,默认 `false` */ + bg?: boolean; + /** 是否为链接按钮,默认 `false` */ + link?: boolean; + /** 是否为圆角按钮,默认 `false` */ + round?: boolean; + /** 是否为圆形按钮,默认 `false` */ + circle?: boolean; + /** 确认按钮的 `PopConfirm` 气泡确认框相关配置 */ + popConfirm?: PopConfirm; + /** 是否为加载中状态,默认 `false` */ + loading?: boolean; + /** 自定义加载中状态图标组件 */ + loadingIcon?: string | Component; + /** 按钮是否为禁用状态,默认 `false` */ + disabled?: boolean; + /** 图标组件 */ + icon?: string | Component; + /** 是否开启原生 `autofocus` 属性,默认 `false` */ + autofocus?: boolean; + /** 原生 `type` 属性,默认 `button` */ + nativeType?: "button" | "submit" | "reset"; + /** 自动在两个中文字符之间插入空格 */ + autoInsertSpace?: boolean; + /** 自定义按钮颜色, 并自动计算 `hover` 和 `active` 触发后的颜色 */ + color?: string; + /** `dark` 模式, 意味着自动设置 `color` 为 `dark` 模式的颜色,默认 `false` */ + dark?: boolean; + /** 自定义元素标签 */ + tag?: string | Component; + /** 点击按钮后触发的回调 */ + btnClick?: ({ + drawer, + button + }: { + /** 当前 `Drawer` 信息 */ + drawer: BtnClickDrawer; + /** 当前 `button` 信息 */ + button: BtnClickButton; + }) => void; +}; + +interface DrawerOptions extends DrawerProps { + /** 内容区组件的 `props`,可通过 `defineProps` 接收 */ + props?: any; + /** 是否隐藏 `Drawer` 按钮操作区的内容 */ + hideFooter?: boolean; + /** 确认按钮的 `PopConfirm` 气泡确认框相关配置 */ + popConfirm?: PopConfirm; + /** 点击确定按钮后是否开启 `loading` 加载动画 */ + sureBtnLoading?: boolean; + /** + * @description 自定义抽屉标题的内容渲染器 + * @see {@link https://element-plus.org/zh-CN/component/drawer.html#%E6%8F%92%E6%A7%BD} + */ + headerRenderer?: ({ + close, + titleId, + titleClass + }: { + close: Function; + titleId: string; + titleClass: string; + }) => VNode | Component; + /** 自定义内容渲染器 */ + contentRenderer?: ({ + options, + index + }: { + options: DrawerOptions; + index: number; + }) => VNode | Component; + /** 自定义按钮操作区的内容渲染器,会覆盖`footerButtons`以及默认的 `取消` 和 `确定` 按钮 */ + footerRenderer?: ({ + options, + index + }: { + options: DrawerOptions; + index: number; + }) => VNode | Component; + /** 自定义底部按钮操作 */ + footerButtons?: Array; + /** `Drawer` 打开后的回调 */ + open?: ({ + options, + index + }: { + options: DrawerOptions; + index: number; + }) => void; + /** `Drawer` 关闭后的回调(只有点击右上角关闭按钮或空白页或按下了esc键关闭页面时才会触发) */ + close?: ({ + options, + index + }: { + options: DrawerOptions; + index: number; + }) => void; + /** `Drawer` 关闭后的回调。 `args` 返回的 `command` 值解析:`cancel` 点击取消按钮、`sure` 点击确定按钮、`close` 点击右上角关闭按钮或空白页或按下了esc键 */ + closeCallBack?: ({ + options, + index, + args + }: { + options: DrawerOptions; + index: number; + args: any; + }) => void; + /** 输入焦点聚焦在 `Drawer` 内容时的回调 */ + openAutoFocus?: ({ + options, + index + }: { + options: DrawerOptions; + index: number; + }) => void; + /** 输入焦点从 `Drawer` 内容失焦时的回调 */ + closeAutoFocus?: ({ + options, + index + }: { + options: DrawerOptions; + index: number; + }) => void; + + /** 点击底部取消按钮的回调,会暂停 `Drawer` 的关闭. 回调函数内执行 `done` 参数方法的时候才是真正关闭对话框的时候 */ + beforeCancel?: ( + done: Function, + { + options, + index + }: { + options: DrawerOptions; + index: number; + } + ) => void; + /** 点击底部确定按钮的回调,会暂停 `Drawer` 的关闭. 回调函数内执行 `done` 参数方法的时候才是真正关闭对话框的时候 */ + beforeSure?: ( + done: Function, + { + options, + index, + closeLoading + }: { + options: DrawerOptions; + index: number; + closeLoading: Function; + } + ) => void; +} + +export type { ButtonProps, DrawerOptions, ArgsType, DrawerProps, EventType }; diff --git a/src/router/modules/components.ts b/src/router/modules/components.ts index 830cea5d97..053840169b 100644 --- a/src/router/modules/components.ts +++ b/src/router/modules/components.ts @@ -18,6 +18,14 @@ export default { title: $t("menus.pureDialog") } }, + { + path: "/components/drawer", + name: "DrawerPage", + component: () => import("@/views/components/drawer/index.vue"), + meta: { + title: $t("menus.pureDrawer") + } + }, { path: "/components/message", name: "Message", diff --git a/src/views/components/dialog/index.vue b/src/views/components/dialog/index.vue index 8f045da78e..c9c0dd4673 100644 --- a/src/views/components/dialog/index.vue +++ b/src/views/components/dialog/index.vue @@ -280,11 +280,11 @@ function onUpdateClick() { }); } -// popconfirm 确认框 +// Popconfirm 确认框 function onPopconfirmClick() { addDialog({ width: "30%", - title: "popconfirm确认框示例", + title: "Popconfirm确认框示例", popconfirm: { title: "是否确认修改当前数据" }, contentRenderer: () =>

点击右下方确定按钮看看效果吧

}); @@ -519,7 +519,7 @@ function onSureBtnLoading() { 关闭后的回调 嵌套的弹框 更改弹框自身属性值 - popconfirm确认框 + Popconfirm确认框 diff --git a/src/views/components/drawer/form.vue b/src/views/components/drawer/form.vue new file mode 100644 index 0000000000..f5383d6a40 --- /dev/null +++ b/src/views/components/drawer/form.vue @@ -0,0 +1,47 @@ + + + diff --git a/src/views/components/drawer/formPrimitive.vue b/src/views/components/drawer/formPrimitive.vue new file mode 100644 index 0000000000..af4bc34c58 --- /dev/null +++ b/src/views/components/drawer/formPrimitive.vue @@ -0,0 +1,22 @@ + + + diff --git a/src/views/components/drawer/index.vue b/src/views/components/drawer/index.vue new file mode 100644 index 0000000000..bc952cbad9 --- /dev/null +++ b/src/views/components/drawer/index.vue @@ -0,0 +1,502 @@ + + + From 7a3c1ab3cdc192ae7a4d4991a705a617bc582280 Mon Sep 17 00:00:00 2001 From: xiaoxian521 <1923740402@qq.com> Date: Wed, 25 Sep 2024 16:57:19 +0800 Subject: [PATCH 2/2] =?UTF-8?q?docs:=20=E6=9B=B4=E6=96=B0=E7=89=B9?= =?UTF-8?q?=E5=88=AB=E4=BB=A3=E7=A0=81=E8=B4=A1=E7=8C=AE=E5=90=8D=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en-US.md | 19 ++++++++++--------- README.md | 19 ++++++++++--------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/README.en-US.md b/README.en-US.md index 65051fc655..bb48a45827 100644 --- a/README.en-US.md +++ b/README.en-US.md @@ -180,17 +180,18 @@ You are very welcome to join![Raise an issue](https://github.com/pure-admin/vu Thank you very much for your in-depth understanding of the source code and your outstanding contributions to the `pure-admin` organization ❤️ -| **Contributor** | **SpecificCode** | -| :---------------------------------------------: | :------------------------------------------------------------------------------: | -| [hb0730](https://github.com/hb0730) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=hb0730) | -| [o-cc](https://github.com/o-cc) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=o-cc) | +| **Contributor** | **SpecificCode** | +| :---------------------------------------------: | :----------------------------------------------------------: | +| [hb0730](https://github.com/hb0730) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=hb0730) | +| [o-cc](https://github.com/o-cc) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=o-cc) | | [yj-liuzepeng](https://github.com/yj-liuzepeng) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=yj-liuzepeng) | -| [skyline523](https://github.com/skyline523) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=skyline523) | +| [skyline523](https://github.com/skyline523) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=skyline523) | | [shark-lajiao](https://github.com/shark-lajiao) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=shark-lajiao) | -| [WitMiao](https://github.com/WitMiao) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=WitMiao) | -| [QFifteen](https://github.com/QFifteen) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=QFifteen) | -| [edgexie](https://github.com/edgexie) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=edgexie) | -| [way-jm](https://github.com/way-jm) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=way-jm) | +| [WitMiao](https://github.com/WitMiao) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=WitMiao) | +| [QFifteen](https://github.com/QFifteen) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=QFifteen) | +| [edgexie](https://github.com/edgexie) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=edgexie) | +| [way-jm](https://github.com/way-jm) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=way-jm) | +| [simple-hui](https://github.com/simple-hui) | [code](https://github.com/pure-admin/vue-pure-admin/commits?author=simple-hui) | ## Git Contribution submission specification diff --git a/README.md b/README.md index 7eb6ff1eb7..d001c88b98 100644 --- a/README.md +++ b/README.md @@ -181,17 +181,18 @@ docker run -dp 8080:80 --name pure-admin vue-pure-admin 非常感谢你们能深入了解源码并对 `pure-admin` 组织作出优秀贡献 ❤️ -| **贡献人** | **具体代码** | -| :---------------------------------------------: | :------------------------------------------------------------------------------: | -| [hb0730](https://github.com/hb0730) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=hb0730) | -| [o-cc](https://github.com/o-cc) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=o-cc) | +| **贡献人** | **具体代码** | +| :---------------------------------------------: | :----------------------------------------------------------: | +| [hb0730](https://github.com/hb0730) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=hb0730) | +| [o-cc](https://github.com/o-cc) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=o-cc) | | [yj-liuzepeng](https://github.com/yj-liuzepeng) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=yj-liuzepeng) | -| [skyline523](https://github.com/skyline523) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=skyline523) | +| [skyline523](https://github.com/skyline523) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=skyline523) | | [shark-lajiao](https://github.com/shark-lajiao) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=shark-lajiao) | -| [WitMiao](https://github.com/WitMiao) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=WitMiao) | -| [QFifteen](https://github.com/QFifteen) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=QFifteen) | -| [edgexie](https://github.com/edgexie) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=edgexie) | -| [way-jm](https://github.com/way-jm) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=way-jm) | +| [WitMiao](https://github.com/WitMiao) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=WitMiao) | +| [QFifteen](https://github.com/QFifteen) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=QFifteen) | +| [edgexie](https://github.com/edgexie) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=edgexie) | +| [way-jm](https://github.com/way-jm) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=way-jm) | +| [simple-hui](https://github.com/simple-hui) | [代码](https://github.com/pure-admin/vue-pure-admin/commits?author=simple-hui) | ## `Git` 贡献提交规范