Vue3 函数式弹窗的实例小结
作者:-小龙人
这篇文章主要介绍了Vue3 函数式弹窗的实例小结,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
运行环境
- vue3
- vite
- ts
- element-plus
开发与测试
1. 使用h、render函数创建Dialog
- 建议可在plugins目录下创建dialog文件夹,创建index.ts文件,代码如下
import { h, render } from "vue"; /** * 函数式弹窗 * @param component 组件 * @param options 组件参数 * @returns */ function createDialog(component: any, options: any) { return new Promise((resolve, reject) => { // 创建一个div节点 const mountNode = document.createElement("div"); // 将div节点拼接到Dom的body节点下 document.body.appendChild(mountNode); // 使用h函数创建节点 const vNode = h(component, { ...options, // 注意: vue子组件emit回调事件名称必须以on开头 onSubmit: data => { resolve(data); // 移除节点 document.body.removeChild(mountNode); }, onCancel: data => { reject(data); // 移除节点 document.body.removeChild(mountNode); } }); // 渲染Dialog render(vNode, mountNode); }); } export default createDialog;
2. 全局挂载函数式弹窗
在main.ts中引入弹窗,并挂载在app上
// 引入函数式弹窗 import Dialog from "@/plugins/dialog"; const app = createApp(App); // 挂载到app app.config.globalProperties.$dialog = Dialog;
3. 测试
3.1 创建一个弹窗组件 testDialog.vue
<template> <el-dialog v-model="dialogVisible" title="测试函数式弹窗" width="50%"> <span>{{ props.content }}</span> <template #footer> <span class="dialog-footer"> <el-button @click="handleCancel">Cancel</el-button> <el-button type="primary" @click="handleSubmit"> Submit </el-button> </span> </template> </el-dialog> </template> <script lang="ts" setup> import { reactive, toRefs } from "vue"; // 注意: 需要按需引入使用到的第三方UI组件 import { ElDialog, ElButton } from "element-plus"; const props = withDefaults( defineProps<{ show?: boolean; // moadl开关 content?: string; // 内容 }>(), {} ); const emits = defineEmits(["submit", "cancel"]); const state = reactive({ dialogVisible: props.show }); const { dialogVisible } = toRefs(state); /** submit */ const handleSubmit = () => { // 回调 emits("submit", { action: "submit", msg: "submit back" }); // 关闭弹窗 dialogVisible.value = false; }; /** cancel */ const handleCancel = () => { // 回调 emits("cancel", { action: "cancel", msg: "cancel back" }); // 关闭弹窗 dialogVisible.value = false; }; </script>
3.2 函数式调用弹窗
<template> <!-- 动态函数式弹窗 --> <div class="test_dialog"> <el-button @click="openModal">调用函数式弹窗</el-button> </div> </template> <script lang="ts" setup> import { getCurrentInstance } from "vue"; import TestDialog from "./testDialog.vue"; // 通过全局的上下文拿到 proxy 属性 const { proxy } = getCurrentInstance(); // 调用函数式弹窗 const openModal = () => { // 调用弹窗 proxy .$dialog(TestDialog, { show: true, content: "调用弹窗成功了!" }) .then(res => { // submit console.log(res); }) .catch(error => { // cancel 回调 console.log(error); }); }; </script> <style lang="scss" scoped> .test_dialog { padding: 50px; } </style>
3.3 测试效果
问题
非原生的html元素无法渲染,如elements-plus组件无法在弹窗渲染
因为使用h函数无法渲染第三方UI,需要在弹窗中单独引入,如上面测试代码使用的element-plus的modal和button都需要按需引入一次。如果没有引入弹窗都不会show出来,控制台会给于警告如下截图,通过这个截图也可以看到,h函数是帮我们将弹窗组件拼接到了DOM中,组件的参数一并拼接了进去,与传统的调用方式近似。
在调用dialog的代码中,ts会有代码警告
可以全局申明下挂载的dialog,可直接在main.ts添加下面的申明
// 全局申明下$dialog,可以去除调用时ts的警告 declare module "vue" { export interface ComponentCustomProperties { $dialog: any; } }
到此这篇关于Vue3 函数式弹窗的文章就介绍到这了,更多相关Vue3 函数式弹窗内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!