背景:
项目中需要展示一些协议内容,因为要调用页面很多,每个页面引用组件很麻烦,需要使用到插件处理,vue2的实现https://blog.csdn.net/lx6091543wwwcctv/article/details/138908571,同步一下vue3的插件实现。
1.首先实现弹框组件
model.vue
也可以加入输入框,可以通过confirm方法把输入的值传过去
<template>
<div v-show="visible">
<div class="mask"></div>
<div class="popbg">
<p>{{ title }}</p>
<button @click="handleCancel()">取消</button>
<button @click="handleConfirm()">确定</button>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
interface Props {
visible: boolean;
close?: () => void;
confirm?: (data:any) => void;
}
const props = defineProps<Props>();
let title = ref('1232142341')
let visible = ref(true)
const handleCancel = () => {
visible.value = false;
props.close?.();
};
const handleConfirm = () => {
visible.value = false;
props.confirm?.(title.value);
};
</script>
<style scoped>
.mask{position: absolute;position: fixed;left: 0;top: 0;background: #2f2e2e; width:100%;height:100%;opacity:0.6;z-index:9999;}
.popbg{position: fixed;top: 0;left: 0;right: 0;bottom: 0;margin: auto;background-color: #fff;border-radius: 20px;width: 800px;height: 400px;z-index: 10000;}
</style>
2.创建一个用于创建和管理弹框的插件:
globalModel.ts
import { App, createVNode,VNode,render,createApp} from 'vue';
import modal from './model.vue';
export const GlobalModalKey = Symbol() as InjectionKey<any>;
const Execute = {
install(app:App) {
function createDialog(): Promise<any> {
return new Promise((resolve, reject) => {
const Vnode: VNode = createVNode(modal2,{
visible: true,
title:'zunjingdeslefu',
close: () => {
reject("close");
document.body.removeChild(container);
},
confirm: (res: any) => {
resolve(res);
render(null, container);
document.body.removeChild(container);
},
});
const container = document.createElement('div');
render(Vnode, container)
document.body.appendChild(container);
});
}
//需要用app.provide,通过 app.provide注入一个应用范围内所有组件都可以使用的值
app.provide(GlobalModalKey,createDialog)
}
};
export default Execute;
也可以用createApp方式实现,createDialog方法代码如下
function createDialog(): Promise<any>{
return new Promise((resolve, reject) => {
const capp = createApp(modal2,{
visible: true,
title:'zunjingdeslefu',
close: () => {
reject("close");
capp.unmount()//注销
document.body.removeChild(container);
},
confirm: (res: any) => {
resolve(res);
capp.unmount()//注销
document.body.removeChild(container);
},
});
const container = document.createElement('div');
// render(Vnode, container)
capp.mount(container)
document.body.appendChild(container);
});
}
3.在主应用中使用这个插件main.js:
import Execute from '@/plugs/model/globalModel';
app.use(Execute)
4.如何使用
<template>
<button @click="handleClick">点击展示</button>
</template>
<script setup>
import { inject } from 'vue';
import {GlobalModalKey} from '@/plugs/model/globalModel';
const createDialog = inject(GlobalModalKey);
const handleClick = async () => {
createDialog().then(res => {
console.log('同意11')
console.log(res)
}).catch(res => {
console.log('不同意12')
console.log(res)
})
}
</script>