在vue3 + vite 的环境下想写一个函数式弹窗,不过需要在弹窗里重新导入用到的element-plus组件。
有办法不需要再次引用么?
部分代码
main.ts 导入 element-plus 依赖
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
// 导入 弹窗
import Dialog from "@/plugins/dialog/index.js";
...
app.use(ElementPlus);
app.use(Dialog);
弹出框核心代码 plugin/dialog/index.js 代码
import { createApp, defineAsyncComponent } from "vue";
export default {
install(app) {
// 注册全局属性
app.config.globalProperties.$Dialog = (cname, cdata) => {
return new Promise((resolve, reject) => {
const divEle = document.createElement("div");
// 让我们节点挂在到一个dom元素上a
document.body.appendChild(divEle);
const dialog = createApp({
data() {
return {
cdata
};
},
template: `<div><${cname} v-bind="cdata" @submit="submit" @cancel="cancel"></${cname}> </div> `,
methods: {
submit() {
console.log(dialog);
document.body.removeChild(divEle);
resolve(true);
},
cancel(res) {
document.body.removeChild(divEle);
reject(res);
}
},
components: {
[cname]: defineAsyncComponent(() => import(`./common/${cname}.vue`))
}
});
dialog.mount(divEle);
});
};
}
};
这里主要使用 defineAsyncComponent 异步加载,自己已经写好的vue页面。也尝试过将这里修改成用render方法返回h函数,结果组件不识别。
子组件代码
<template>
<el-dialog
v-model="dialogVisible"
title="Tips"
width="30%"
:before-close="handleClose"
>
<span>This is a message</span>
<template #footer>
<span class="dialog-footer">
<el-button @click="handleCancel">Cancel</el-button>
<el-button type="primary" @click="handleConfirm"> Confirm </el-button>
</span>
</template>
</el-dialog>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { ElMessageBox, ElDialog, ElButton } from "element-plus";
import { getCurrentInstance } from "vue";
const { proxy } = getCurrentInstance();
const emit = proxy.$emit;
const dialogVisible = ref(true);
const handleClose = (done: () => void) => {
ElMessageBox.confirm("Are you sure to close this dialog?")
.then(() => {
done();
dialogVisible.value = false;
})
.catch(() => {
// catch error
});
};
const handleCancel = () => {
emit("cancel");
dialogVisible.value = false;
};
const handleConfirm = () => {
emit("submit");
dialogVisible.value = false;
};
</script>
在子组件里必须要手动在引入使用过的element-plus组件例如示例代码:
import { ElMessageBox, ElDialog, ElButton } from "element-plus";
如果能不引入就好了。
父组件代码
<script setup lang="ts">
import { getCurrentInstance } from "vue";
defineOptions({
name: "Welcome"
});
const { proxy } = getCurrentInstance();
function handleTouch() {
proxy.$Dialog("alert", {});
}
</script>
<template>
<div>
<h1>Pure-Admin-Thin(非国际化版本)</h1>
<el-button @click="handleTouch">Touch alert window</el-button>
</div>
</template>