fine-true
Version:
A small and beautiful Vue3 version of the UI Library
68 lines (60 loc) • 1.88 kB
text/typescript
import Message from './component/index';
import withInstall from 'components/utils/withInstall';
import { createVNode, render, VNode } from 'vue';
withInstall(Message);
const messageInstances: Array<VNode> = [];
const methodNames = ['message', 'info', 'success', 'warning', 'error'];
type MessagePropsType = {
type?: string;
message?: string;
duration?: number;
top?: number;
onClose?: () => void;
};
const createMethod = function (type = 'message') {
return function (options: MessagePropsType = {}) {
let top = options.top || 10;
messageInstances.forEach((vm) => {
top += vm?.el?.offsetHeight || 0;
});
const dom = document.createElement('div');
document.body.appendChild(dom);
const vm = createVNode(Message, {
...options,
type,
top,
onClose() {
close(vm);
options.onClose && options.onClose();
},
onDestroy() {
render(null, dom);
dom.parentNode?.removeChild(dom);
},
});
render(vm, dom);
messageInstances.push(vm);
return vm;
};
};
methodNames.forEach((methodName) => {
Message[methodName] = createMethod(methodName);
});
function close(vm: VNode) {
const id = messageInstances.findIndex((instance) => instance === vm);
let length = messageInstances.length;
if (id >= length - 1) return;
messageInstances.splice(id, 1);
const currentVm = vm;
const subtractHeight = currentVm.el?.offsetHeight || 0;
if (!subtractHeight) return;
//reset messageInstances length
length = messageInstances.length;
for (let i = id; i < length; i++) {
const instance = messageInstances[i];
const top = parseInt(instance!.el!.style.top) - subtractHeight;
instance!.component!.props!.top = top;
}
}
export * from './component/index';
export default Message;