背景
在公司低代码大屏开发过程中,有一个需求是在一个大屏中可以点按钮打开另一个嵌入的大屏,一开始的效果是页面加载后两个大屏的资源同时加载,会因为资源加载多和慢导致页面渲染也会有些慢,所以这里使用了声明式弹窗组件封装了大屏壳子,使得每一个大屏都可以通过函数创建和销毁。
思路
首先我们需要一个通用的方法可以去创建弹窗、展示弹窗、销毁弹窗,然后外部调用这个方法传入大屏壳子组件和一些prop参数及实践,最后调用这个方法。
代码实现
先封装一个通用的弹窗钩子函数
// usePopup.js
import { createApp } from 'vue';
const createEl = () => {
const el = document.createElement('div');
el.setAttribute(
'style',
`
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2000;
height: 100%;
background-color: var( -- el-overlay-color-lighter);
overflow: auto;
`,
);
return el;
};
export const usePopup = (container) => {
const el = createEl();
let app;
const createMyApp = () => createApp(container);
const show = () => {
app = createMyApp();
app.mount(el);
document.body.appendChild(el);
};
const destroy = () => {
if (app) app.unmount();
document.body.removeChild(el);
};
return {
show,
destroy,
};
};
根据业务逻辑封装大屏弹窗方法
// useNestedPage.js
import { h } from 'vue';
import NestedPage from './index.vue';
import { usePopup } from '../../../utils/usePopup';
export const useNestedPage = () => {
let nestedPageInstance;
const close = () => {
nestedPageInstance.destroy();
};
const show = (options) => {
nestedPageInstance = usePopup(
h(NestedPage, {
...options,
onClose: () => {
close();
},
}),
);
nestedPageInstance.show();
};
return {
show,
close,
};
};
声明式弹窗使用
const { show } = useNestedPage()
// options为一系列弹窗内展示组件及NestedPage组件的props参数
show(options)