| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- import { createVNode, render, type AppContext } from 'vue'
- import MessageComponent from '@/components/Message.vue'
- export interface MessageOptions {
- type?: 'info' | 'success' | 'warning' | 'error'
- title?: string
- message?: string
- duration?: number
- closable?: boolean
- ctx?: AppContext
- onClose?: () => void
- }
- export type MessageTypeOptions = Omit<MessageOptions, 'type' | 'message'>
- export interface MessageIntance {
- id: string
- close: () => void
- }
- export type MessageFn = (message: string, options?: MessageTypeOptions) => MessageIntance
- export interface Message {
- (options: MessageOptions): MessageIntance
- info: MessageFn
- success: MessageFn
- error: MessageFn
- warning: MessageFn
- closeAll: () => void
- _context?: AppContext | null
- }
- const instances: MessageIntance[] = []
- let wrap: HTMLDivElement | null = null
- let seed = 0
- const defaultOptions: MessageOptions = {
- duration: 3000,
- }
- const message: Message = (options: MessageOptions) => {
- const id = 'message-' + seed++
- const props = {
- ...defaultOptions,
- ...options,
- id,
- }
- if (!wrap) {
- wrap = document.createElement('div')
- wrap.className = 'message-wrap'
- wrap.style.cssText = `
- width: 100%;
- position: fixed;
- top: 0;
- left: 0;
- z-index: 6000;
- pointer-events: none;
- display: flex;
- flex-direction: column;
- box-sizing: border-box;
- padding: 15px;
- background-color: rgba(255, 255, 255, 0);
- transition: all 1s ease-in-out;
- align-items: center;
- `
- document.body.appendChild(wrap)
- }
- const vm = createVNode(MessageComponent, props, null)
- const div = document.createElement('div')
- vm.appContext = options.ctx || message._context || null
- vm.props!.onClose = options.onClose
- vm.props!.onDestroy = () => {
- if (wrap && wrap.childNodes.length <= 1) {
- wrap.remove()
- wrap = null
- }
- render(null, div)
- }
- render(vm, div)
- wrap.appendChild(div.firstElementChild!)
- const instance = {
- id,
- close: () => vm?.component?.exposed?.close(),
- }
- instances.push(instance)
- return instance
- }
- message.success = (msg: string, options?: MessageTypeOptions) => message({ ...options, type: 'success', message: msg })
- message.info = (msg: string, options?: MessageTypeOptions) => message({ ...options, type: 'info', message: msg })
- message.warning = (msg: string, options?: MessageTypeOptions) => message({ ...options, type: 'warning', message: msg })
- message.error = (msg: string, options?: MessageTypeOptions) => message({ ...options, type: 'error', message: msg })
- message.closeAll = function() {
- for (let i = instances.length - 1; i >= 0; i--) {
- instances[i].close()
- }
- }
- export default message
|