在我们的网页界面上总是需要制作一些二级面板或者弹框提示的东西,这里自己参考一些博客的方法进行了一个自定义弹框插件的实现研究
在最开始时,弹框组件我们可以写死在需要展示的页面上,通过v-if或者v-show来控制其显示,控制其显示的标志可以通过子父组件之间的emit传出事件方法去通知,这样的方法的确可以解决
二级面板以及弹框提示的问题,但是这种方式来控制显得不灵活而且没有可复用性。
因此想到能不能写成弹框的插件来复用,即我们写一个二级弹框的载体,通过这个载体我们在上面放置我们需要的组件进行显示。
按照这样的思想在网上搜索了一番:
发现在Vue2中可以根据Vue.extend的方法通过继承来实现dialog框的复用,在Vue3中取消了这样的方法,但是可以使用getcurrentInstance来获取全局的属性,并且对其进行注册,具体方法如下
import { createVNode, render } from 'vue'; import type { App } from "vue"; const Message: any = function (DialogComponent:any, options: any) { const container = document.createElement('div'); container.className = "dialog"; container.style.width = '100%'; container.style.height = '89%'; container.style.zIndex = '9999'; container.style.position = 'fixed'; container.style.background = 'rgba(213, 213, 213, 0.88)'; container.style.top = '6.5%'; container.style.bottom = '10%'; //创建虚拟节点 const vm = createVNode( DialogComponent, options as any, );
//渲染 render(vm, container);
//默认寻找最初的根元素div,在我的工程中这个div的类名为‘.app-main’,有且仅有唯一 var node = document.querySelector('.app-main'); node.appendChild(container); } export default { install(app: App): void { app.config.globalProperties.$message = Message } }
上述命名为Message的全局变量需要在main.ts中进行注册
注册完后该插件即可被全局使用;
此时我们可以写一个公用的添加组件和移除组件方法对其进行封装
import { isNullOrUndefined } from "util"; class DialogService { AddDialogComponent( ins:any,component: any, options?: any) { let dialog = document.querySelector('.dialog'); if (isNullOrUndefined(dialog)) { if (options) { ins!.appContext?.config?.globalProperties.$message(component, options); } else { ins!.appContext?.config?.globalProperties.$message(component); } } else { //如果存在dialog了 ,则先移除 this.RemoveDialogComponent(); if (options) { ins!.appContext?.config?.globalProperties.$message(component, options); } else { ins!.appContext?.config?.globalProperties.$message(component); } } } RemoveDialogComponent() { let dialog = document.body.querySelector('.dialog'); let child = dialog.firstChild; dialog.removeChild(child); dialog.parentNode.removeChild(dialog); } } export default new DialogService()
这里提供AddDialogComponent( ins:any,component: any, options?: any) 方法来创建dialog,ins表示的是在创建时的当前getCurrentInstance(),component表示我们需要插入的组件
options是一个可选值,表示对组件的注入数据props。
这里提供的一些代码仍然有不足之处,比如多个二级面板同时存在时的问题等等,应该还能够继续完善,上述有错之处或者可以优化指出还请指正