Skip to content

Commit

Permalink
feat: add close
Browse files Browse the repository at this point in the history
  • Loading branch information
unliar committed Jul 9, 2021
1 parent 9d96828 commit c20d07a
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 25 deletions.
63 changes: 52 additions & 11 deletions src/components/common/Message/index.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
<template>
<transition name="message-fade">
<div v-show="visible" :class="['message-box', `message-box--${type}`]">
<transition
name="message-fade"
@before-leave="beforeLeave"
@after-leave="destroy"
>
<div
v-show="visible"
:class="['message-box', `message-box--${type}`]"
:style="computedStyle"
>
<slot>
<p v-if="!isHTML" class="message-content">
{{ $props.content }}
Expand All @@ -16,11 +24,14 @@ import {
onMounted,
onBeforeUnmount,
defineProps,
getCurrentInstance,
computed,
defineEmit,
} from "vue";
// 是否可见
const visible = ref(false);
const emit = defineEmit(["destroy"]);
const destroy = () => emit("destroy");
const props = defineProps({
/**
* 弹窗警告类型
Expand All @@ -47,15 +58,31 @@ const props = defineProps({
*/
duration: {
type: Number,
default: 30, //
default: 3, //
validator: (v: number) => {
return +v > 0;
},
},
/**
* 弹窗关闭时的调用
*/
onClose: Function,
onClose: {
type: Function,
require: true,
default: () => {},
},
/**
* zIndex
*/
offset: { type: Number, default: 20 },
zIndex: { type: Number, default: 0 },
/**
* 标识id
*/
id: {
type: String,
require: true,
},
});
// 开启弹窗
Expand All @@ -68,14 +95,22 @@ const onOpen = () => {
}, props.duration * 1000);
};
const beforeLeave = () => {
props.onClose();
};
const computedStyle = computed(() => {
return {
top: `${props.offset}px`,
zIndex: props.zIndex,
};
});
onMounted(() => {
onOpen();
console.log("message box onMounted", getCurrentInstance());
console.log("message box onMounted");
});
onBeforeUnmount(() => {
if (typeof props.onClose === "function") {
props.onClose();
}
console.log("message box onUnmounted");
});
</script>
Expand All @@ -84,13 +119,19 @@ onBeforeUnmount(() => {
.message-box {
position: fixed;
left: 50%;
top: 20px;
transform: translateX(-50%);
transition: opacity 0.3s, transform 0.4s, top 0.4s;
overflow: hidden;
display: flex;
align-items: center;
background: #909399;
background: #edf2fc;
padding: 15px 15px 15px 20px;
min-width: 280px;
font-size: 16px;
color: #606266;
border: 1px solid #ebeef5;
border-radius: 4px;
overflow: hidden;
}
p {
Expand Down
80 changes: 70 additions & 10 deletions src/components/common/Message/instance.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,55 @@
import { createVNode, render } from "vue";
import Ins from "./index.vue";
import type { MessageInstance, Options } from "./type";
const Message: MessageInstance = (opt?: Options) => {
const cfg = opt || {};
const ContainerClassName = "happy__message";
const c = document.querySelector(`.${ContainerClassName}`);
if (c) {
document.body.removeChild(c);
import type { InstanceQueqe, MessageInstance, Options } from "./type";

const isServer = typeof window === "undefined";

const Queqe: InstanceQueqe = [];
let seed = 5201414;
const Message: MessageInstance = (opts: Options | String) => {
if (isServer) return;
let options: Options = {
content: "",
};
if (typeof opts === "object") {
options = Object.assign(options, opts);
}
if (typeof opts === "string") {
if (opts.length == 0) throw new Error("不能弹出空消息框");
options.content == opts;
}
const vm = createVNode(Ins, { ...cfg });
const container = document.createElement("div");
const id = "message_" + seed++;

const ContainerClassName = "happy__message_container_" + id;
let container = document.createElement("div");
container.className = ContainerClassName;

let offset = options.offset || 20;
console.log("配置高度", offset);
Queqe.forEach(v => {
console.log("实例高度", v.el?.offsetHeight);
offset += (v.el?.offsetHeight || 0) + 16;
});
console.log(Queqe, offset);
offset += 16;
const userOnClose = options.onClose;
options = {
...options,
id,
offset,
onClose: () => {
remove(id, userOnClose);
},
};
// console.log(options, Queqe);
const vm = createVNode(Ins, options);
(vm.props as any).onDestroy = () => {
console.log("销毁实例");
render(null, container);
};
render(vm, container);
document.body.appendChild(container);
Queqe.push(vm);
document.body.appendChild(container.firstElementChild as Element);
};

Message.closeAll = () => {};
Expand All @@ -25,4 +62,27 @@ Message.info = () => {};

Message.error = () => {};

const remove = (id: string, userOnclose?: () => void) => {
const index = Queqe.findIndex(vm => {
const tid = vm.component?.props.id;
return tid == id;
});
if (index === -1) return;
const vm = Queqe[index];
if (!vm) return;
userOnclose?.();
const removedHeight = vm.el?.offsetHeight || 0;
Queqe.splice(index, 1);
const len = Queqe.length;
if (len < 1) return;
for (let i = index; i < len; i++) {
console.log("更改 fixed 高度 全部减去 - " + removedHeight, Queqe);
let top = [];
}
};

export default Message;

export const useMessage = () => {
return Message;
};
6 changes: 6 additions & 0 deletions src/components/common/Message/type.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { VNode } from "vue";

export type MessageType = "warn" | "error" | "success" | "info";

export type MessageInstance = {
Expand All @@ -15,4 +17,8 @@ export type Options = {
duration?: number; // 显示时长
onClose?: () => void; // 关闭时的调用
type?: MessageType;
offset?: number; // 垂直偏移
id?: string;
};

export type InstanceQueqe = Array<VNode>;
11 changes: 7 additions & 4 deletions src/views/home/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,13 @@ const getList = (req: API.ARTICLE.GetArticleListRequest) => {
};
onMounted(async () => {
M({
content: "222",
type: "error",
});
setInterval(() => {
M({
content: "222",
type: "success",
onClose: () => console.log("onclose gogogog"),
});
}, 3000);
await getList(props.query ?? {});
});
</script>
Expand Down

0 comments on commit c20d07a

Please sign in to comment.