feat: 添加ReDrawer demo

This commit is contained in:
liaohui 2024-09-03 11:32:52 +08:00
parent 6bccf3a83d
commit 99d67ed1f7
6 changed files with 582 additions and 1 deletions

View File

@ -83,6 +83,7 @@ menus:
pureFive: "500"
pureComponents: Components
pureDialog: Dialog
pureDrawer: Drawer
pureMessage: Message Tips
pureVideo: Video
pureSegmented: Segmented

View File

@ -83,6 +83,7 @@ menus:
pureFive: "500"
pureComponents: 组件
pureDialog: 函数式弹框
pureDrawer: 函数式抽屉
pureMessage: 消息提示
pureVideo: 视频
pureSegmented: 分段控制器

View File

@ -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",

View File

@ -0,0 +1,47 @@
<script setup lang="ts">
import { ref } from "vue";
// props
export interface FormProps {
formInline: {
user: string;
region: string;
};
}
// props
// https://cn.vuejs.org/guide/typescript/composition-api.html#typing-component-props
const props = withDefaults(defineProps<FormProps>(), {
formInline: () => ({ user: "", region: "" })
});
// vue prop prop Vue
// reactive ref Ref value reactive
// newFormInline === props.formInline true props.formInline
// props.formInline
// https://cn.vuejs.org/guide/components/props.html#one-way-data-flow
const newFormInline = ref(props.formInline);
</script>
<template>
<el-form :model="newFormInline">
<el-form-item label="姓名">
<el-input
v-model="newFormInline.user"
class="!w-[220px]"
placeholder="请输入姓名"
/>
</el-form-item>
<el-form-item label="城市">
<el-select
v-model="newFormInline.region"
class="!w-[220px]"
placeholder="请选择城市"
>
<el-option label="上海" value="上海" />
<el-option label="浙江" value="浙江" />
<el-option label="深圳" value="深圳" />
</el-select>
</el-form-item>
</el-form>
</template>

View File

@ -0,0 +1,22 @@
<script setup lang="ts">
import { useVModel } from "@vueuse/core";
// props
export interface FormProps {
data: string;
}
// props
// https://cn.vuejs.org/guide/typescript/composition-api.html#typing-component-props
const props = withDefaults(defineProps<FormProps>(), {
data: () => ""
});
// 使 vueuse
const emit = defineEmits(["update:data"]);
const data = useVModel(props, "data", emit);
</script>
<template>
<el-input v-model="data" class="!w-[220px]" placeholder="请输入内容" />
</template>

View File

@ -0,0 +1,502 @@
<script setup lang="tsx">
import {
addDrawer,
closeDrawer,
closeAllDrawer,
updateDrawer
} from "@/components/ReDrawer/index";
import { cloneDeep, debounce } from "@pureadmin/utils";
import { message } from "@/utils/message";
import { createVNode, h, ref } from "vue";
import formPrimitive from "./formPrimitive.vue";
import forms, { type FormProps } from "./form.vue";
function onBaseClick() {
addDrawer({
title: "基础用法",
contentRenderer: () => <p>抽屉内容-基础用法</p> // jsx .vuejsxscriptlang="tsx"
});
}
function onModalClick() {
addDrawer({
title: "无背景遮罩层",
modal: false,
contentRenderer: () => <p>抽屉内容-无背景遮罩层</p>
});
}
// 600ms
const onoOpenDelayClick = debounce(
() =>
addDrawer({
title: "延时2秒打开抽屉",
openDelay: 2000 - 600,
contentRenderer: () => <p>抽屉内容-延时2秒打开抽屉</p>
}),
600
);
function onCloseDelayClick() {
addDrawer({
title: "延时2秒关闭抽屉",
closeDelay: 2000,
contentRenderer: () => <p>抽屉内容-延时2秒关闭抽屉</p>
});
}
function onShowCloseClick() {
addDrawer({
title: "不显示右上角关闭按钮图标",
showClose: false,
contentRenderer: () => <p>抽屉内容-不显示右上角关闭按钮图标</p>
});
}
function onBeforeCloseClick() {
addDrawer({
title: "禁止通过键盘ESC关闭",
closeOnPressEscape: false,
contentRenderer: () => <p>抽屉内容-禁止通过键盘ESC关闭</p>
});
}
function onCloseOnClickModalClick() {
addDrawer({
title: "禁止通过点击modal关闭",
closeOnClickModal: false,
contentRenderer: () => <p>抽屉内容-禁止通过点击modal关闭</p>
});
}
function onHideFooterClick() {
addDrawer({
title: "隐藏底部取消、确定按钮",
hideFooter: true,
contentRenderer: () => <p>抽屉内容-隐藏底部取消确定按钮</p>
});
}
function onHeaderRendererClick() {
addDrawer({
title: "自定义头部",
showClose: false,
headerRenderer: ({ close, titleId, titleClass }) => (
// jsx
<div class="flex flex-row justify-between">
<h4 id={titleId} class={titleClass}>
自定义头部
</h4>
<el-button type="danger" onClick={close}>
关闭
</el-button>
</div>
),
contentRenderer: () => <p>抽屉内容-自定义头部</p>
});
}
function onFooterRendererClick() {
addDrawer({
title: "自定义底部",
footerRenderer: ({ options, index }) => (
<el-button onClick={() => closeDrawer(options, index)}>
{options.title}-{index}
</el-button>
),
contentRenderer: () => <p>抽屉内容-自定义底部</p>
});
}
function onFooterButtonsClick() {
addDrawer({
title: "自定义底部按钮",
footerButtons: [
{
label: "按钮1",
size: "small",
type: "success",
btnClick: ({ drawer: { options, index }, button }) => {
console.log(options, index, button);
closeDrawer(options, index);
}
},
{
label: "按钮2",
text: true,
bg: true,
btnClick: ({ drawer: { options, index }, button }) => {
console.log(options, index, button);
closeDrawer(options, index);
}
},
{
label: "按钮3",
size: "large",
type: "warning",
btnClick: ({ drawer: { options, index }, button }) => {
console.log(options, index, button);
closeDrawer(options, index);
}
}
],
contentRenderer: () => <p>抽屉内容-自定义底部按钮</p>
});
}
function onOpenClick() {
addDrawer({
title: "打开后的回调",
open: ({ options, index }) => message({ options, index } as any),
contentRenderer: () => <p>抽屉内容-打开后的回调</p>
});
}
function onCloseCallBackClick() {
addDrawer({
title: "关闭后的回调",
closeCallBack: ({ options, index, args }) => {
console.log(options, index, args);
let text = "";
if (args?.command === "cancel") {
text = "您点击了取消按钮";
} else if (args?.command === "sure") {
text = "您点击了确定按钮";
} else {
text = "您点击了右上角关闭按钮或空白页或按下了esc键";
}
message(text);
},
contentRenderer: () => <p>抽屉内容-关闭后的回调</p>
});
}
// 便使 addDrawer
function onNestingClick() {
addDrawer({
title: "嵌套的抽屉",
size: "50%",
contentRenderer: ({ index }) => (
<el-button
onClick={() =>
addDrawer({
title: `${index + 1}个子抽屉`,
size: "40%",
contentRenderer: ({ index }) => (
<el-button
onClick={() =>
addDrawer({
title: `${index + 1}个子抽屉`,
size: "30%",
contentRenderer: () => (
<>
<el-button round onClick={() => closeAllDrawer()}>
哎呦你干嘛赶快关闭所有抽屉
</el-button>
</>
)
})
}
>
点击打开第{index + 1}个子抽屉
</el-button>
)
})
}
>
点击打开第{index + 1}个子抽屉
</el-button>
)
});
}
// contentRenderer
function onUpdateClick() {
const curPage = ref(1);
addDrawer({
title: `${curPage.value}`,
contentRenderer: () => (
<>
<el-button
disabled={curPage.value <= 1}
onClick={() => {
curPage.value -= 1;
updateDrawer(`${curPage.value}`);
}}
>
上一页
</el-button>
<el-button
onClick={() => {
curPage.value += 1;
updateDrawer(`${curPage.value}`);
}}
>
下一页
</el-button>
</>
)
});
}
// popConfirm
function onPopConfirmClick() {
addDrawer({
size: "30%",
title: "popConfirm确认框示例",
popConfirm: { title: "是否确认修改当前数据" },
contentRenderer: () => <p>点击右下方确定按钮看看效果吧</p>
});
}
// Form props prop
function onFormOneClick() {
addDrawer({
size: "30%",
title: "结合Form表单第一种方式",
contentRenderer: () => forms,
props: {
//
formInline: {
user: "菜虚鲲",
region: "浙江"
}
},
closeCallBack: ({ options, args }) => {
// options.props
const { formInline } = options.props as FormProps;
const text = `姓名:${formInline.user} 城市:${formInline.region}`;
if (args?.command === "cancel") {
//
message(`您点击了取消按钮,当前表单数据为 ${text}`);
} else if (args?.command === "sure") {
message(`您点击了确定按钮,当前表单数据为 ${text}`);
} else {
message(
`您点击了右上角关闭按钮或空白页或按下了esc键当前表单数据为 ${text}`
);
}
}
});
}
// Formh https://cn.vuejs.org/api/render-function.html#h
const formInline = ref({
user: "菜虚鲲",
region: "浙江"
});
const resetFormInline = cloneDeep(formInline.value);
function onFormTwoClick() {
addDrawer({
size: "30%",
title: "结合Form表单第二种方式",
contentRenderer: () =>
h(forms, {
formInline: formInline.value
}),
closeCallBack: () => {
message(
`当前表单数据为 姓名:${formInline.value.user} 城市:${formInline.value.region}`
);
//
formInline.value = cloneDeep(resetFormInline);
}
});
}
// FormcreateVNode https://cn.vuejs.org/guide/extras/render-function.html#creating-vnodes
const formThreeInline = ref({
user: "菜虚鲲",
region: "浙江"
});
const resetFormThreeInline = cloneDeep(formThreeInline.value);
function onFormThreeClick() {
addDrawer({
size: "30%",
title: "结合Form表单第三种方式",
contentRenderer: () =>
createVNode(forms, {
formInline: formThreeInline.value
}),
closeCallBack: () => {
message(
`当前表单数据为 姓名:${formThreeInline.value.user} 城市:${formThreeInline.value.region}`
);
//
formThreeInline.value = cloneDeep(resetFormThreeInline);
}
});
}
// Form使jsx
// forms forms contentRenderer: () => formsh(forms) createVNode(createVNode)
// 使jsx `contentRenderer: () => <forms formInline={formFourInline.value} />` forms `script` forms
// tsx 使 `contentRenderer: () => <forms formInline={formFourInline.value} />` forms return forms
const formFourInline = ref({
user: "菜虚鲲",
region: "浙江"
});
const resetFormFourInline = cloneDeep(formFourInline.value);
function onFormFourClick() {
addDrawer({
size: "30%",
title: "结合Form表单第四种方式",
contentRenderer: () => <forms formInline={formFourInline.value} />,
closeCallBack: () => {
message(
`当前表单数据为 姓名:${formFourInline.value.user} 城市:${formFourInline.value.region}`
);
//
formFourInline.value = cloneDeep(resetFormFourInline);
}
});
}
// prop primitive demo
const formPrimitiveParam = ref("Hello World");
const resetFormPrimitiveParam = ref(formPrimitiveParam.value);
function onFormPrimitiveFormClick() {
addDrawer({
size: "30%",
title: "子组件 prop 为 primitive 类型 demo",
contentRenderer: () =>
h(formPrimitive, {
data: formPrimitiveParam.value,
"onUpdate:data": val => (formPrimitiveParam.value = val)
}),
closeCallBack: () => {
message(`当前表单内容:${formPrimitiveParam.value}`);
//
formPrimitiveParam.value = resetFormPrimitiveParam.value;
}
});
}
function onBeforeCancelClick() {
addDrawer({
title: "点击底部取消按钮的回调",
contentRenderer: () => (
<p>抽屉内容-点击底部取消按钮的回调会暂停抽屉的关闭</p>
),
beforeCancel: (done, { options, index }) => {
console.log(
"%coptions, index===>>>: ",
"color: MidnightBlue; background: Aquamarine; font-size: 20px;",
options,
index
);
// done(); //
}
});
}
function onBeforeSureClick() {
addDrawer({
title: "点击底部确定按钮的回调",
contentRenderer: () => (
<p>
抽屉内容-点击底部确定按钮的回调会暂停抽屉的关闭经常用于新增修改抽屉内容后调用接口
</p>
),
beforeSure: (done, { options, index }) => {
console.log(
"%coptions, index===>>>: ",
"color: MidnightBlue; background: Aquamarine; font-size: 20px;",
options,
index
);
// done(); //
}
});
}
function onSureBtnLoading() {
addDrawer({
sureBtnLoading: true,
title: "点击底部确定按钮可开启按钮动画",
contentRenderer: () => <p>抽屉内容-点击底部确定按钮可开启按钮动画</p>,
beforeSure: (done, { closeLoading }) => {
closeLoading(); //
// done() //
setTimeout(() => done(), 800);
}
});
}
</script>
<template>
<el-card shadow="never">
<template #header>
<div class="card-header">
<span class="font-medium">
二次封装 Element Plus
<el-link
href="https://element-plus.org/zh-CN/component/drawer.html"
target="_blank"
style="margin: 0 4px 5px; font-size: 16px"
>
Drawer
</el-link>
</span>
</div>
<el-link
href="https://github.com/pure-admin/vue-pure-admin/tree/main/src/views/components/drawer"
target="_blank"
>
代码位置 src/views/components/drawer
</el-link>
</template>
<el-space wrap>
<el-button @click="onBaseClick">基础用法</el-button>
<el-button @click="onModalClick"> 无背景遮罩层 </el-button>
<el-button @click="onoOpenDelayClick"> 延时2秒打开抽屉 </el-button>
<el-button @click="onCloseDelayClick"> 延时2秒关闭抽屉 </el-button>
<el-button @click="onShowCloseClick">
不显示右上角关闭按钮图标
</el-button>
<el-button @click="onBeforeCloseClick"> 禁止通过键盘ESC关闭 </el-button>
<el-button @click="onCloseOnClickModalClick">
禁止通过点击modal关闭
</el-button>
<el-button @click="onHideFooterClick"> 隐藏底部取消确定按钮 </el-button>
<el-button @click="onHeaderRendererClick"> 自定义头部 </el-button>
<el-button @click="onFooterRendererClick"> 自定义底部 </el-button>
<el-button @click="onFooterButtonsClick"> 自定义底部按钮 </el-button>
<el-button @click="onOpenClick"> 打开后的回调 </el-button>
<el-button @click="onCloseCallBackClick"> 关闭后的回调 </el-button>
<el-button @click="onNestingClick"> 嵌套的抽屉 </el-button>
<el-button @click="onUpdateClick"> 更改抽屉自身属性值 </el-button>
<el-button @click="onPopConfirmClick">popConfirm确认框</el-button>
</el-space>
<el-divider />
<el-space wrap>
<el-button @click="onFormOneClick">
结合Form表单第一种方式
</el-button>
<el-button @click="onFormTwoClick">
结合Form表单第二种方式
</el-button>
<el-button @click="onFormThreeClick">
结合Form表单第三种方式
</el-button>
<el-button @click="onFormFourClick">
结合Form表单第四种方式
</el-button>
<el-button @click="onFormPrimitiveFormClick">
子组件 prop primitive 类型
</el-button>
</el-space>
<el-divider />
<el-space wrap>
<el-button @click="onBeforeCancelClick">
点击底部取消按钮的回调会暂停抽屉的关闭
</el-button>
<el-button @click="onBeforeSureClick">
点击底部确定按钮的回调会暂停抽屉的关闭经常用于新增修改抽屉内容后调用接口
</el-button>
<el-button @click="onSureBtnLoading">
点击底部确定按钮可开启按钮动画
</el-button>
</el-space>
</el-card>
</template>