返回顶部
首页 > 资讯 > 前端开发 > JavaScript >Vue2 Dialog弹窗函数式调用实践示例
  • 318
分享到

Vue2 Dialog弹窗函数式调用实践示例

Vue2 Dialog弹窗函数式调用Vue2 Dialog 2023-01-15 18:01:35 318人浏览 独家记忆
摘要

目录前言Vue2 的弹窗常用的使用方式第一种:将弹窗写在上下文中第二种:原型上注入全局方法第三种:通过依赖注入的方式合理的使用方式功能实现结语前言 Dialog 对话框组件几乎是每

前言

Dialog 对话框组件几乎是每个前端项目必不可少的组件,通常是在保留当前页面状态并屏蔽其他用户输入的情况下,与用户交互并承载相关操作。

在 BOM 的方法中,alertprompt 都是以前用来做类似功能的方法,但是这些浏览器内置方法会完全停止网页代码执行,对于贫乏的前端线程资源来说实在是过于僵硬。于是便产生了各种各样的 js 弹窗。

今天就来谈谈在前端框架 Vue 2 版本中的弹窗组件的相关实现以及我个人认为的最佳实践。

Vue2 的弹窗常用的使用方式

对于 Vue2 的 UI 框架,坊间比较火的有 element-ui antd-vue vant-ui 等等,不过他们在弹窗的使用方法上几乎都是一致的。下面我们以 element-ui 中的组件为例讲讲这些使用方式的缺点

第一种:将弹窗写在上下文中

这种方式不用多讲,使用起来肯定是最麻烦的一种,这意味着你每次想使用这个弹窗组件都要写一遍负责显隐的状态以及方法,尽量只在唯一场景里使用,不具备复用条件。

第二种:原型上注入全局方法

即是通过往 Vue.prototype 中注入弹窗的方法,使你可以在 vue 上下文中使用 this.$confirm 诸如此类的方法来使用他们的弹窗功能。

这种调用方式曾经几乎是所有 vue2 全局 api 的解决方法,一时间各种插件都有了各种各样的全局 api。例如 vuex 的 this.$store、 EventBus 的 this.$bus 等等。

这种方式在使用上虽然非常方便,但也有如下一些缺点

上下文污染,一个 vue 的全局 this 里面,什么东西都可以有,不论是全局方法、还是全局变量,都可以放在 Vue.prototype 里面,例如前一个例子,如果复杂的弹窗需要在各种其他前端文件内打开,大概率也是用这种方式将弹窗打开和关闭方法都注入到全局 this 中使用。

类型丢失,无论你是全局状态管理还是事件总线,在使用的时候都是各种黑盒,全局方法来自于什么插件、需要传什么参数、返回什么东西,全然无感,只能想办法寻找蛛丝马迹去溯源。

只能在 vue 上下文中使用,在 vue 文件外就无法使用了。就好比 React 无法在 React 上下文之外 setState 一样难受。

第三种:通过依赖注入的方式

这种方式和第二种几乎一样,通过顶层组件 provider 出对应的函数方法,之后在子组件中 inject 进来。 一样存在着 provider 的上下文污染,也丢失了类型,并且依旧只能在 vue 上下文中使用,灵活性一样差。

合理的使用方式

除了上述所说的问题之外

综合以上的缺点,我认为一个弹窗最佳的使用方式在 Vue2 中使用方式是这样:

    <template>
        <button @click="open">打开弹窗</button>
    </template>
    <script>
        import openDialog from 'my-dialog'
        export default {
            methods: {
                open() {
                    openDialog()
                        .then(() => {})
                        .catch(() => {})
                        .finally(() => {})
                }
            }
        }
    </script>

也可以在其他文件中,例如:

    // api.ts
    import openDialog from 'my-dialog'
    const getUserInfo = () => {
        return fetch('/xxx/api').then(() => {
            openDialog('success')
        })
    }

功能实现

废话不多说,直接上核心代码

// dialog.ts
import Vue, { ComponentInstance } from "vue";
import ConfirmDialog from "./confirm-dialog.vue";
export let index = 1000;
export const cache = new Set<string>();
export function openDialog(component: ComponentInstance) {
	const div = document.createElement("div");
	const el = document.createElement("div");
	const id = 'dialog-' + Math.random();
	div.appendChild(el);
	document.body.appendChild(div);
	const ComponentConstructor = Vue.extend(component);
	return (propsData = {}, parent = undefined) => {
		let instance = new ComponentConstructor({
			propsData,
			parent,
		}).$mount(el);
		const destroyDialog = () => {
			if (cache.has(id)) return;
			if (instance && div.parentnode) {
				cache.add(id);
				(instance as any).visible = false;
                // 延时是为了在关闭动画执行完毕后卸载组件
				setTimeout(() => {
					cache.delete(id);
					instance.$destroy();
					// @ts-ignore
					instance = null;
					div.parentNode && div.parentNode.removeChild(div);
				}, 1000);
			}
		};
		// visible控制
		if ((instance as any).visible !== undefined) {
			// 支持sync/v-model
			instance.$watch("visible", (val) => {
				!val && destroyDialog();
			});
			Vue.nextTick(() => ((instance as any).visible = true));
		}
		return new Promise((resolve, reject) => {
			// emit 一个 done 事件关闭
			instance.$once("done", (data: any) => {
				destroyDialog();
				resolve(data);
			});
			// emit 一个 cancel 事件取消
			instance.$once("cancel", (data: any) => {
				destroyDialog();
				reject(data);
			});
		});
	};
}
export function confirmDialog(content: string, editable?: boolean) {
	return openDialog(ConfirmDialog as any)({ content, editable });
}

使用方式和结果可以通过下面这个例子进行查看

stackblitz.com/edit/vitejs…

在例子中,我们可以将任意 vue 组件包装进 openDialog Api 中,只需要在组件的 data 里写入一个 visible 属性,而后续在组件方法中调用 this.$emits('done') 或者 this.$emits('cancel') 就可以对应 openDialog 方法返回 Promise 的 then 回调和 catch 回调。

可以自定义传参、自定义内容、自定义事件,自定义返回,灵活性直接拉满。

而且,方法不限于任何上下文,在任何文件内都可以使用,实现了真正的函数式调用 Vue2 的弹窗组件。

但是这个方法确实也有那么一点点不方便的地方,如果有掘友看得出来,可以在评论下方说说。

结语

这篇文章其实没多少东西,甚至代码都是我一年多前就写的,在受到 React hooks 的启发后,我就觉得函数式编程非常的爽,就尝试将项目中的全局变量都剥离 vue 上下文,包括 dialogmessage 组件,之后摒弃 vuexpinia 这种强绑上下文的状态管理库,改用 Vue.observable,就可以很方便的将业务与 UI 完全抽离。所有变量和方法都可以通过 import 追溯,更重要的是这种模式更契合 typescript,类型提示也很轻易跟上来了。

以上就是本篇文章的所有内容了,后续我会封装 v2 和 v3 的函数式弹窗组件,并发布到 npm 上,到时候再更新链接到文章里,更多关于Vue2 Dialog弹窗函数式调用的资料请关注编程网其它相关文章!

--结束END--

本文标题: Vue2 Dialog弹窗函数式调用实践示例

本文链接: https://lsjlt.com/news/177823.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Vue2 Dialog弹窗函数式调用实践示例
    目录前言Vue2 的弹窗常用的使用方式第一种:将弹窗写在上下文中第二种:原型上注入全局方法第三种:通过依赖注入的方式合理的使用方式功能实现结语前言 Dialog 对话框组件几乎是每...
    99+
    2023-01-15
    Vue2 Dialog弹窗函数式调用 Vue2 Dialog
  • vue3.2自定义弹窗组件结合函数式调用示例详解
    目录前言手写弹窗组件组件调用函数式调用如何使用含样式完整源码效果图前言 涉及的vue3知识点/API,createApp defineProps defineEmits <sc...
    99+
    2024-04-02
  • vue弹窗父子组件调用问题示例详解
    目录一、vue弹窗 父子组件 emit 传图片二、vue父组件调用子组件里的不同方法一、vue弹窗 父子组件 emit 传图片 1、:modal-append-to-body=&qu...
    99+
    2024-04-02
  • python链式函数调用的示例分析
    小编给大家分享一下python链式函数调用的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!链式函数调用你可以在一行代码内调用多个函数。def a...
    99+
    2023-06-27
  • 如何使用layer.alert回调函数执行关闭弹窗
    这篇文章将为大家详细讲解有关如何使用layer.alert回调函数执行关闭弹窗,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。对于layer.alert()弹出层来说,想要...
    99+
    2024-04-02
  • SparkSQL开窗函数分析使用示例
    目录聚合函数和开窗函数开窗函数聚合开窗函数排序开窗函数开窗函数能在每行的最后一行都显示聚合函数的结果,所以聚合函数可以用作开窗函数 聚合函数和开窗函数 聚合函数是将多行变成一行,如果...
    99+
    2023-01-28
    SparkSQL开窗函数 SparkSQL窗口函数
  • PHP 函数调用中的最佳实践与反模式
    最佳实践:1. 使用命名空间和别名减少冗余。2. 使用可选参数提高灵活性。3. 进行参数类型检查增强健壮性。反模式:1. 滥用别名和重复命名空间。2. 缺少类型检查会降低可靠性。 PH...
    99+
    2024-04-17
    最佳实践 函数调用 反模式 代码可读性
  • 遵循golang函数最佳实践的示例
    遵循 go 函数最佳实践至关重要,包括使用接收器函数、限制函数参数、使用可选命名参数、保持函数简洁以及适当的错误处理。通过这些原则,您可以编写可读、可维护且高效的 go 代码。 Go ...
    99+
    2024-05-01
    java php golang
  • Golang函数的并发调用实践分享
    作为一门高效、轻量、并发支持良好的编程语言,Golang 的函数并发调用是一项很重要的特性。在这篇文章中,本文将分享一些关于 Golang 函数并发调用的实践经验,希望能对 Golang 开发者有所帮助。一、Goroutine 的使用Gor...
    99+
    2023-05-18
    Golang 并发调用 实践分享
  • 在CMD窗口中调用python函数的实现
    目录1.问题背景2.解决方案2.1.Python文件中只包含一个函数,而且不需要输入任何参数2.2.Python文件中有多个函数,调用其中某一个,并且输入参数1.问题背景 针对目前愈...
    99+
    2024-04-02
  • C++调用matlab函数的实例
    目录一、封装matlab函数二、 编译matlab函数三 、C++环境配置四、mwArray数组的运用一、封装matlab函数 首先把matlab代码封装成函数形式,下面举一个例子,...
    99+
    2024-04-02
  • MySQL窗口函数OVER使用示例详细讲解
    目录窗口函数测试数据表及数据窗口函数空窗口窗口中只有 ORDER BY窗口中只有 PARTITION BY 时同时有 PARTITION BY 与 ORDER BY窗口函数 OVER (PARTITION BY xxx ...
    99+
    2023-01-05
    MySQL 窗口函数 窗口函数OVER MySQL OVER函数
  • SQL窗口函数OVER用法实例整理
    目录OVER的定义语法用法示例SUM后的开窗函数排序ROWS|RANGE参考总结OVER的定义 OVER用于为行定义一个窗口,它对一组值进行操作,不需要使用GROUP BY子句对数据进行分组,能够在同一行中同时返回基础行...
    99+
    2024-04-02
  • PHP 函数的调用机制及最佳实践
    php 函数调用采用传值调用机制,函数内部对参数值的修改不会影响外部变量。采用最佳实践包括:按需传递参数、函数拆分、可选参数、默认值以及类型提示。按值传递示例:$numbers = [1...
    99+
    2024-04-16
    最佳实践 函数调用
  • PHP 函数调用性能优化实践分享
    为提升 php 应用性能,优化函数调用至关重要。实践包括:减少不必要的函数调用(如重复调用、传入不必要参数)利用函数别名和缩写使用内联函数(提升简单函数调用的性能) PHP 函数调用性...
    99+
    2024-04-17
    php 函数调用优化 优化实践
  • Shell之function函数的定义及调用示例
    目录function函数的定义及调用function函数的定义 function函数的调用【位置传参】函数使用return返回值【位置传参】函数的调用【数组传参】function函数的定义及调用 将一些相对独立...
    99+
    2022-08-08
    Shellfunction函数 Shell function
  • JavaScript函数调用经典实例代码
    目录JavaScript函数调用经典例题JS函数的定义与调用方法总结JavaScript函数调用经典例题 1.输入框判断是不是闰年 2.随机数判断是不是闰年 3.输入框判断是不是质数...
    99+
    2024-04-02
  • JavaScript函数语法、函数调用和函数返回实例分析
    这篇文章主要介绍了JavaScript函数语法、函数调用和函数返回实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇JavaScript函数语法、函数调用和函数返回实例分析...
    99+
    2024-04-02
  • python如何实现链式函数调用
    这篇文章主要介绍了python如何实现链式函数调用,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。链式函数调用感谢你能够认真阅读完这篇文章,希...
    99+
    2024-04-02
  • Sql Server 开窗函数Over()的使用实例详解
    利用over(),将统计信息计算出来,然后直接筛选结果集 declare @t table( ProductID int, ProductName varchar(20), ProductTy...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作