vue3动态加载对话框的方法实例
作者:程序员德子 发布时间:2024-05-09 15:16:55
标签:vue3,加载,对话框
简介
介绍使用vue3的异步组件动态管理对话框组件,简化对话框组件使用方式。本文使用的是vue3、typescript、element_plus完成的示例。
常规方式使用对话框
一般情况下,使用对话框组件,会使用v-model进行双向绑定,通过visible变量控制对话框的显示和关闭。常规方式有一个弊端,自定义组件中使用<el-dialog>,需要通过父组件控制自定义组件是否展示。
<template>
<ElButton type="primary" @click="openGeneral()">常规方式打开Modal</ElButton>
<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="dialogVisible = false">Cancel</el-button>
<el-button type="primary" @click="dialogVisible = false"
>Confirm</el-button
>
</span>
</template>
</el-dialog>
</template>
<script setup lang="ts">
// This starter template is using Vue 3 <script setup> SFCs
// Check out https://v3.vuejs.org/api/sfc-script-setup.html#sfc-script-setup
import {ref } from 'vue';
const dialogVisible = ref(false)
const openGeneral=()=>{
dialogVisible.value=true
}
</script>
异步动态加载
先看使用异步组件进行动态加载对话框的方式。异步组件使用到的是defineAsyncComponent接口,只有使用到这个组件,才会从网络上加载。动态操作使用的useDzModal
使用方式
<template>
<ElButton type="primary" @click="openTestModalAsync()">动态异步打开TestModal</ElButton>
</template>
<script setup lang="ts">
import { defineAsyncComponent,ref } from 'vue';
import { ElMessageBox } from 'element-plus';
import { useDzModal } from './dzmodal'
// 异步加载组件
const TestModalAsync = defineAsyncComponent(()=>import('./components/TestModal.vue'))
const dzmodal = useDzModal()
// # 通过dzmodal动态操作对话框
const openTestModalAsync=()=>{
dzmodal.open(TestModalAsync,{
name:'张三'
})
.then(res=>{
if(res.type==='ok'){
ElMessageBox.alert('TestModal点击了确定');
}else{
ElMessageBox.alert('TestModal点击了取消');
}
})
}
</script>
TestModal.vue
<script setup lang="ts">
import { reactive, ref, defineProps } from 'vue'
const emits = defineEmits(['ok','cancel'])
const props = defineProps({
name: String
});
const dialogVisible = ref(true)
const resultData= reactive({
type:'ok',
data:{}
})
</script>
<template>
<el-dialog
v-model="dialogVisible"
title="TestModal"
width="30%"
>
<div>通过DzModal打开TestModal</div>
<div>外部传入:{{ name }}</div>
<template #footer>
<span class="dialog-footer">
<el-button @click="emits('cancel',{});dialogVisible = false">Cancel</el-button>
<el-button type="primary" @click="emits('ok',{});dialogVisible = false"
>Confirm</el-button
>
</span>
</template>
</el-dialog>
</template>
<style scoped>
</style>
使用结果
动态操作对话框的实现
动态操作对话框,主要思路是动态创建虚拟dom节点,将对话框组件渲染到组件上,核心关键点是要动态创建的节点的上下文为当前app上下文vm.appContext = this._app._context
DzModalService.ts
import { App, inject, Plugin, h, render} from 'vue'
import { ComponentOptions } from 'vue';
export const DzModalSymbol = Symbol()
export class DzModalResult{
type: 'ok'|'cancel'|'string' = 'ok'
body?:any= undefined
}
export class DzModalService{
private _app?:App=undefined
constructor(app:App){
this._app=app;
}
public open(modal:ComponentOptions, props?: any):Promise<DzModalResult>{
return new Promise((reslove,reject)=>{
if(!this._app){
reject('_app is undefined')
return;
}
const container = document.createElement("div");
document.body.appendChild(container)
// 这里需要合并props,传入到组件modal
const vm = h(modal, {
...props,
onOk:(data?:any)=>{
// 弹出框关闭时移除节点
document.body.removeChild(container)
reslove(this.ok(data));
},
onCancel:(data?:any)=>{
reslove(this.cancel(data));
}
});
// 这里很重要,关联app上下文
vm.appContext = this._app._context
render(vm,container);
});
}
public ok(data?:any):DzModalResult{
const result = new DzModalResult();
result.type='ok';
result.body=data;
return result;
}
public cancel(data?:any):DzModalResult{
const result = new DzModalResult();
result.type='cancel';
result.body=data;
return result;
}
}
export function useDzModal(): DzModalService {
const dzModal = inject<DzModalService>(DzModalSymbol)
if(!dzModal){
throw new Error('No DzModal provided!')
}
return dzModal;
}
const plugin: Plugin = {
install(app:App, options?:{[key:string]:any}){
const dzModal = new DzModalService(app)
app.config.globalProperties.$dzModal= dzModal
app.provide(DzModalSymbol, dzModal)
}
}
export default plugin;
main.ts
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import DzModal from './dzmodal'
createApp(App)
.use(ElementPlus)
.use(DzModal) // 安装 dzmodal插件
.mount('#app')
通过异步组件方式引入对话框组件
打开对话框组件
来源:https://juejin.cn/post/7080287482771669028


猜你喜欢
- 目录openpyxl介绍openpyxl安装openpyxl基本概念openpyxl对excel进行操作新建excel打开已存在的文件读取单
- WebSocket与HTTP协议的主要区别HTTP 和 WebSocket 协议的区别 HTTP 是单向的,而 WebSocket 是双向的
- mixins混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式。混合对象可以包含任意组件选项。当组件使用混合对象时
- 1. 确认已经安装了NT/2000和SQL Server的最新补丁程序,不用说大家应该已经安装好了,但是我觉得最好还是在这里提醒一下。2.
- 调用tf.reset_default_graph()重置计算图当在搭建网络查看计算图时,如果重复运行程序会导致重定义报错。为了可以在同一个线
- 本文介绍Python3使用PyMySQL连接数据库,并实现简单的增删改查。什么是PyMySQL?PyMySQL是Python3.x版本中用于
- 本文实例讲述了Python编程实现及时获取新邮件的方法。分享给大家供大家参考,具体如下:#-*- encoding: utf-8 -*-im
- 看书笔记db file scattered read DB ,db file sequential read DB,free buffer
- 前言给新的环境安装pip install tensorflow,结果报错了。跟着我分析解决一波。报错原因这个红字已经说的很清楚了。ERROR
- 今天晚上,笔者接到客户的一个需要,那就是:对多分类结果的每个类别进行指标评价,也就是需要输出每个类型的精确率(precision),召回率(
- #!/bin/env python # -*- coding: utf-8 -*- #filename: peartes
- pytorch默认使用单精度float32训练模型,原因在于:使用float16训练模型,模型效果会有损失,而使用double(float6
- 虚拟环境的创建命令行窗口中使用conda create -n 环境名 python=所需python版本即可创建虚拟环境pytorch的gp
- 本文实例为大家分享了python3实现证件照背景替换的具体代码,供大家参考,具体内容如下import cv2import numpy as
- 前言WSGI 有三个部分, 分别为服务器(server), 应用程序(application) 和中间件(middleware). 已经知道
- 本文实例讲述了php多进程中的阻塞与非阻塞操作。分享给大家供大家参考,具体如下:我们通过pcntl_fork来创建子进程,使用pcntl_w
- 1.批量处理所谓的批处理就是批量处理cmd里面的命令。python要想实现批处理功能需要导入os库,然后利用批处理的命令为os.system
- 在网页制作中,表单中的对象总是给人一种单调与沉闷的感觉,比如说按钮、文本框等,它们一成不变的模样与颜色
- 一、利用直方图的方式进行批量的图片缺陷检测(方法简单)二、步骤(完整代码见最后)2.1灰度转换(将原图和要检测对比的图分开灰度化)灰度化的作
- 本文实例讲述了php中debug_backtrace、debug_print_backtrace和匿名函数用法。分享给大家供大家参考。具体分