Vue3 + TS 关于如何将组件进行挂载body 例如:$message / $notify - 戴向天

大家好!我叫戴向天

QQ群:602504799

如若有不理解的,可加QQ群进行咨询了解

关于messgaenotification 的组件内容我就不贴出来了。若想要的就直接加群获取吧。

使用方式

  this.$message({
    message: "这个是$message",
  });
  this.$notify({
    message: "这个是$notify",
  });

效果图
Vue3 + TS 关于如何将组件进行挂载body 例如:$message / $notify - 戴向天_第1张图片

fileName: main.ts

import { createApp } from 'vue'
import App from './App.vue'
import mixin from './utils/use'

createApp(App).use(mixin)

TS Properties注册
该文件直接放在src目录里面即可,若还是显示无法读取,则就重启软件
fileName: vue.d.ts


interface INotify {
    title?: string;
    message?: string;
    type?: 'success' | 'error' | 'info' | 'warning';
    duration?: number;
    iconClass?: string;
    showClose?: boolean;
    dangerouslyUseHTMLString?: boolean
    customClass?: string;
    offset?: number;
    onClick?: Function
}

interface IMessage {
    message?: string;
    type?: string;
    iconClass?: string;
    dangerouslyUseHTMLString?: boolean;
    customClass?: string;
    duration?: number;
    showClose?: boolean;
    center?: boolean;
    onClose?: Function;
    offset?: number;
}


declare module '@vue/runtime-core' {
    interface ComponentCustomOptions {

    }

    interface ComponentCustomProperties {
        $notify: (options?: INotify) => void | {
            success: (options?: INotify) => void;
            error: (options?: INotify) => void;
            info: (options?: INotify) => void;
            warning: (options?: INotify) => void;
        };
        $message: (options?: IMessage) => void | {
            success: (options?: IMessage) => void;
            error: (options?: IMessage) => void;
            info: (options?: IMessage) => void;
            warning: (options?: IMessage) => void;
        };
    }

}

export { }

fileName: use.ts

import { App, createApp } from 'vue'

// 通知组件
import Notification from "@/components/notification/notification.vue";
// 信息提醒
import YMessage from '@/components/y-message/y-message.vue'

function appendToBody(app: App) {

    const el = document.createElement("div")
    document.body.appendChild(el)

    app.mount(el);
    if (el.firstChild) {
        document.body.appendChild(el.firstChild)
    }

    document.body.removeChild(el)
}

function $zIndex() {
    const arr = [...document.all].map(
        (e) => +window.getComputedStyle(e).zIndex || 0,
    );
    return arr.length ? Math.max(...arr) + 1 : 0;
}


function mount(node: any) {
    const instances: any[] = []
    let seed = 1

    // 关闭指定的message
    function close(id: string, userOnClose?: Function) {
        let index = -1
        const len = instances.length
        const instance = instances.filter((instance, i) => {
            if (instance.$el.id === id) {
                index = i;
                return true;
            }
            return false;
        })[0];
        if (!instance) return;
        if (typeof userOnClose === 'function') {
            userOnClose(instance);
        }
        instances.splice(index, 1);
        if (len <= 1) return;

        const position = instance.position;
        const removedHeight = instance.$el.offsetHeight;
        for (let i = index; i < len - 1; i++) {
            if (instances[i].position === position) {
                instances[i].verticalOffset = parseInt(instances[i].$el.style.top, 10) - removedHeight - 16
                instances[i].$el.style.zIndex = $zIndex()
            }
        }
    }

    const nodeHandler: any = (options: { [key: string]: any }) => {
        setTimeout(() => {
            const messageNode = createApp({
                ...node,
                mounted() {
                    const id = 'message_' + seed++;
                    const position = this.position
                    let verticalOffset = options.offset || 0;
                    instances.filter(item => item.position === position).forEach(item => {
                        verticalOffset += item.$el.offsetHeight + 20;
                    });
                    verticalOffset += 20;
                    this.verticalOffset = verticalOffset
                    this.visible = true;
                    this.$el.id = id
                    this.$el.style.zIndex = $zIndex()
                    const userOnClose = options.onClose
                    this.onClose = function () {
                        close(id, userOnClose);
                    };
                    if (options.onClick && typeof options.onClick === 'function') {
                        this.onClick = options.onClick
                    }

                    this.destroy = messageNode.unmount
                    this.startTimer();
                    instances.push(this);
                }
            }, options)
            appendToBody(messageNode)
        })
    }

    ['success', 'warning', 'info', 'error'].forEach((type: string) => {
        nodeHandler[type] = (options: { [key: string]: any }) => {
            if (typeof options === 'string') {
                options = {
                    message: options
                };
            }
            options.type = type;
            return nodeHandler(options);
        }
    });

    nodeHandler.close = close;
    // 关闭所有notify
    nodeHandler.closeAll = function () {
        for (let i = instances.length - 1; i >= 0; i--) {
            instances[i].close();
        }
    };
    return nodeHandler
}

export default {
    install(app: App) {
        // Notification 通知
        app.config.globalProperties.$notify = mount(Notification)
        // Message 消息提示
        app.config.globalProperties.$message = mount(YMessage)

    }
}

你可能感兴趣的:(前端,组件,vue,vue3,ts,message,notify,戴向天)