Vue之函数式弹窗组件的封装原理

news/2024/4/26 19:09:15/文章来源:https://blog.csdn.net/qq_31281245/article/details/127389986

vue的封装组件大家都知道,通过props,event,slot 即可实现一个特殊的弹框组件。代码如下:

<template><div><Alert v-if="show">这是一条提示信息</Alert><button @click="show = true">显示</button></div>
</template>
<script>import Alert from '../component/alert.vue';export default {components: { Alert },data () {return {show: false}}}</script>

但是这种弹框通常都有以下缺点:

1. 每个使用的地方都必须要先引用注册。

2. 需要预先将封装好的 组件放置在模板中。

3. 需要额外的data来控制 弹框 的显示状态。

4. 弹框的位置,是当前组件位置,并非在body下。并且有可能会被其它组件遮挡。

基于以上问题,所以说,普通的组件封装是对使用者来说不是很友好,如果我们在类似于全局封装的函数中(例如:axios 响应中)引入,则当前这种就比较不好的了。那么如何能实现一个优雅的组件呢?

其实对比原生的 window.alert("这是一个弹框")

我们就可以知道,一个优雅的组件莫过于,能用JavaScript随时随地调用的组件

类似于:

它可以在任何位置进行使用,无需单独引入,并且接收两个参数。

content: 提示内容

duration: 持续时间,默认1.5秒

最终样子如下:

this.$alert.info({content: '我是一个弹窗',duration: 3
});

下来我们就一起看看如何实现这个全局弹框组件。

一:我们可以通过最终调用值发现,this.$alert。 很明显指的就是vue的实例。也就是说我们声明完成的一个alert则会是一个js文件,并且我们将它挂载在了 vue.prototype之上。

由此我们可以断定。这个vue文件的main.js中是这样写的

// ... 其余代码省略
import alert from '@/components/alert.js'Vue.prototype.$alert = alertnew Vue({...其余代码,render: h => h(App)
}).$mount('#app')

而我们在调用 this,$alert 的时候初始化了一个info方法,那么这个方法一定是存在于 alert这个js文件中。并且是一个初始化弹窗方法, 接收两个参数,一个是弹窗内容,一个是弹窗显示时间。

// alert.js... 省略代码const notice = ({content = '',duration = 1.5 
}) =>{// 传递给弹窗的实际组件方法中// 此处暂不编写。
}export default {info(options){return notice(options)    }
}

到目前为止,我们根据最后弹窗的使用方法,简单的推断出了 alert.js这个文件。但是有这个文件可不够,我们还是需要一个页面。也就是说,我们也还是需要一个dom 展示页面的,不然我们的弹窗样式无法定义。

所以我们基于 alert.js的同级目录,新增一个页面,alert.vue 用来展示 弹框的样式

<template><div class="alert"><div class="alert-main" v-for="item in notices" :key="item.name"><div class="alert-content">{{ item.content }}</div></div></div>
</template>
<script>export default {data () {return {notices: []}}}</script>
<style>.alert{position: fixed;width: 100%;top: 16px;left: 0;text-align: center;pointer-events: none;}.alert-content{display: inline-block;padding: 8px 16px;background: #fff;border-radius: 3px;box-shadow: 0 1px 6px rgba(0, 0, 0, .2);margin-bottom: 8px;}</style>

因为我们通过已知的业务,通知可以是多条的,并且每一条都可以有不同的展示时间,所以在弹窗展示这里,我们用notices 数组来保存一个个的单内容。

细心的朋友会发现,这个页面与以往的组件页面不一致,那是因为,我们本次的组件是需要JavaScript来调用的,而非传递数据改变其状态调用。所以我们不需要props 以及 event事件。

接下来,只要给数组 notices 增加数据,这个提示组件就能显示内容了,我们先假设,最终会通过 JS 调用 Alert 的一个方法 add,并将 content 和 duration 传入进来:

所以我们修改 alert.vue这个页面的内容

<script>let seed = 0;function getUuid() {return 'alert_' + (seed++);}export default {data () {return {notices: []}},methods: {add (notice) {const name = getUuid();let _notice = Object.assign({name: name}, notice);this.notices.push(_notice);// 定时移除,单位:秒const duration = notice.duration;setTimeout(() => {this.remove(name);}, duration * 1000);},remove (name) {const notices = this.notices;for (let i = 0; i < notices.length; i++) {if (notices[i].name === name) {this.notices.splice(i, 1);break;}}}}}</script>

add方法为,我们每一条传递进来的提示数据,我们通过添加一个name字段,来表示这条数据是唯一的值。在每一次add的时候都push到notices 的数组中,并且根据传递进来的时间,利用 setTimeout 设置其展示时间。

同时,当传递进来的时间到期后,我们通过remove 方法将其从 notices 的数组中进行移除。

所以在这一步,我们就必须将当前的弹窗进行实例化,因为我们不是常规使用组件方法,所以这是哈哈我们使用Vue.extend 或者 newVue 实例化后,利用$mount 挂载到body下。

// notification.js
import alert from './alert.vue';
import Vue from 'vue';alert.newInstance = properties => {const props = properties || {};const Instance = new Vue({data: props,render (h) {return h(alert, {props: props});}});const component = Instance.$mount();document.body.appendChild(component.$el);const alerts = Instance.$children[0];return {add (noticeProps) {alerts.add(noticeProps);},remove (name) {alerts.remove(name);}}
};export default alert;

notification.js 并不是最终的文件,它只是对 alert.vue 添加了一个方法  newInstance,这个方法就是实例化后的 alert 方法。我们通过实例化alert后,获取到alerts。它就是组件alert的组件实例,在newInstance里,我们使用闭包暴漏了两个方法,一个add,一个 remove。

最后我们就可以补全我们最开始预留的代码 alert.js

/ alert.js
import Notification from './notification.js';let messageInstance;function getMessageInstance () {messageInstance = messageInstance || Notification.newInstance();return messageInstance;
}function notice({ duration = 1.5, content = '' }) {let instance = getMessageInstance();instance.add({content: content,duration: duration});
}export default {info (options) {return notice(options);}
}

这就是我们本期所说的,vue之函数式弹窗组件的生成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_25479.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Elasticsearch(ES) 基本知识

ES 学习笔记 ES是一个基于Apache的开源索引库Lucene而构建的 开源、分布式、具有RESTful接口的全文搜索引擎, 还是一个分布式文档数据库. 基本概念 index 索引是具有相似结构的文档的集合, 比如可以有一个商品分类索引, 订单索引. 每个索引都要有唯一的名称, 名称要小写, 通…

CleanMyMac X适用于Mac电脑安全的软件

CleanMyMac X 内部包含有很多不同的功能组件&#xff0c;它们需要以各种各样的方式协同合作&#xff0c;这对我而言也是一个新鲜的设计过程。 我注意到&#xff0c;当我们使用造型不完美的对象更加令人愉悦。无菌的空间和完美的物品&#xff0c;甚至可能会让人产生失真感和排斥…

面试突击91:MD5 加密安全吗?

MD5 是 Message Digest Algorithm 的缩写,译为信息摘要算法,它是 Java 语言中使用很广泛的一种加密算法。MD5 可以将任意字符串,通过不可逆的字符串变换算法,生成一个唯一的 MD5 信息摘要,这个信息摘要也就是我们通常所说的 MD5 字符串。那么问题来了,MD5 加密安全吗? 这…

高可用linux 服务器搭建

最原始的服务部署,为单点部署,即直接把服务部署在一个服务器上。如果服务器出现故障,或者服务因为某个异常而挂掉,则服务就会发生中断。单点部署出现故障的概率最高。 后来,出现了网关,比如 nginx kong 等。如下图所示:这样,所有客户请求都会经过网关,再由网关转发到各…

python的opencv操作记录(七)——短时傅里叶变换(stft)

文章目录DCT-傅立叶变换的局限性STFT 短时傅里叶变换从另一个角度来理解图像的“时域”数据看看fs和t这两个参数再看看怎么划分窗口最后看另外两个出参Zxx返回结构图像的stftDCT-傅立叶变换的局限性 接上一篇DCT的文章&#xff0c;DCT只提取了整个信号域的频率信息&#xff0c…

Python——HTTP代理 Proxy

大佬勿喷 链接: https://pan.baidu.com/s/1Wm0JepiZa9iPn4WoQU3Qdg 提取码: p09g

【计算机毕业设计】基于微信小程序的校园生活服务平台

提供了一些今年最新计算机毕业设计源代码、文档及帮助指导&#xff0c;公众号&#xff1a;一点毕设&#xff0c;领取更多毕设资料。 一.课题概述 随着互联网时代的到来&#xff0c;移动端应用的发展十分迅猛&#xff0c;校园服务类应用 也是不计其数。但大多功能单一&#xf…

Word处理控件Aspose.Words功能演示:使用 Java 将 RTF 转换为 PDF

RTF 格式由 Microsoft 引入&#xff0c;用于创建富文本文档。RTF 的互操作性使得在不同的 Microsoft 产品以及异构操作系统之间交换内容成为可能。但是&#xff0c;有时可能需要将 RTF 转换为 PDF 以用于打印、共享或其他目的。因此&#xff0c;本文介绍了 如何使用 Java 以编程…

干净的代码——一种实用的方法

在对干净代码进行了一些讨论之后&#xff0c;我决定在一篇文章中总结最重要的事情。因为网上有很多关于清洁代码的帖子和信息&#xff0c;我认为一篇新的文章谈论它只是解释一些原则是不值得的。在本文中&#xff0c;我将尝试为您提供清洁代码的实用方法。我不会深入理论&#…

海康大华等录像机、摄像头无法通过GB28181注册到LiveGBS国标平台问题排查方法

LiveGBS常见问题-海康大华宇视华为NVR摄像头无法注册到平台国标平台看不到设备的时候如何抓包及排查1、设备注册后查看不到1.1、防火墙排查1.2、端口排查1.3、IP地址排查1.4、设备TCP/IP配置排查1.5、设备多网卡排查1.6、设备接入配置参数排查1.7、设备尝试修改本地SIP端口1.8、…

Biotin-PEG-Alk,Biotin-PEG-Alkyne,生物素-聚乙二醇-炔烃科研用试剂供应

An English name&#xff1a;Biotin-PEG-Alk&#xff0c;Biotin-PEG-Alkyne Chinese name&#xff1a;生物素-聚乙二醇-炔烃 Item no&#xff1a;X-GF-0267-10k CAS&#xff1a;N/A Formula&#xff1a;N/A MW&#xff1a;Biotin-PEG1-Alkyne/Biotin-PEG2-Alkyne/Biotin-P…

uni-app实战之单击菜单发布->H5的Promise 化在工程项目的实战演练项目心得

H5 开发注意 H5发布到服务器注意&#xff1a; 配置发布后的路径&#xff08;在网站的根目录中发布是可选的&#xff09;&#xff0c;例如发布网站的路径为www.xxx Com/html5&#xff0c;在manifest中编辑json文件中的h5节点&#xff0c;并将base属性添加到路由器下的html5 单…

基于PHP的蔬菜价格查询管理系统设计与实现

目 录 1 引言 1 1.1 课题背景与意义 1 1.2 课题现状与可研究性 1 1.3 本论文研究内容和结构安排 1 2 系统基础概述 2 2.1 软件开发环境 2 2.2 L&#xff0c;Linux操作系统 2 2.3 A&#xff0c;Apache服务器 2 2.4 M&#xff0c;Mysql数据库 3 2.5 P&#xff0c;PHP语言 3 2.5.1…

EXCEL表格-VLOOKUP多对一结果匹配方法(通配符)

❤关注我&#xff0c;不迷路❤ 点击进入EXCEL综合应用场景专栏 在实际使用场景中&#xff0c;通过一个值去匹配另一个值的案例很常见&#xff0c;比如一份学校的信息表&#xff0c;通过姓名查找班级、家长姓名等&#xff0c;均用VLOOKUP函数可以实现&#xff0c;正向查找、逆…

【Coel.学习笔记】莫比乌斯反演

冷知识:百度百科里甚至没有对反演的准确定义……闲话 记得在差不多一年前写扩展欧拉定理的时候我提了一句这周终于把古代猪文搞定了,数论这块的内容就只剩个博弈论了 别提莫比乌斯反演之类的东西,我不想搞甚至刚开始写的时候还笔误把莫反写成了莫队…… 转眼一年过去了,来填…

leetcode 123买卖股票的最佳时机III

买卖股票的最佳时机III 动态规划-分两小组分别计算&#xff08;超时&#xff09; class Solution { public:int partprofit( vector<int>& prices , int start , int end ){if((end-start)<1) return 0;vector<int> dp(end - start , 0);int min prices[s…

视觉检测工作台设计

目 录 摘 要 I Abstract II 第1章 引言 1 1.1研究背景及意义 1 1.2国内外研究现状 2 第2章 总体方案的确定 4 2.1方案拟定 4 2.1.1机械结构 4 2.1. 2控制工艺要求 5 2.1. 3总体方案 5 2.2 设计参数 7 第3章 视觉检测工作台机械系统设计 8 3.1 X-Y数控工作台总体方案的确定 8 3.…

微信公众号查题搜题平台

微信公众号查题搜题平台 本平台优点&#xff1a; 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a; 题库&#xff1a;题库后台&#xff08;点击跳转&#xf…

物联网、区块链、元宇宙和虚拟数字人离普罗大众有多远?

首先&#xff0c;我们最早理解的数字人就是数字虚拟的一个假人&#xff0c;可能看起来很像二次元玩偶的样子。今天我觉得数字人是一种虚拟的数字身份&#xff0c;无所谓你的形象是仿真或是任何形象&#xff0c;包括你在现实中无法实现的形象&#xff0c;你在梦想中所渴望的概念…

【数据结构与算法分析】0基础带你学数据结构与算法分析01--基础数学知识

&#x1f353;个人主页&#xff1a;个人主页 &#x1f4ac;推荐一款模拟面试、刷题神器&#xff0c;从基础到大厂面试题&#xff1a;点击跳转进入网站 &#x1f4e9;如果你想学习算法&#xff0c;以及一些语言基础的知识&#xff0c;那就来这里&#xff1a;​​​​刷题网站 跟…