前端组件库造轮子——Message组件开发教程

前端组件库造轮子——Message组件开发教程

前言

本系列旨在记录前端组件库开发经验,我们的组件库项目目前已在Github开源,下面是项目的部分组件。文章会详细介绍一些造组件库轮子的技巧并且最后会给出完整的演示demo。

image.png

文章旨在总结经验,开源分享,有问题的话也希望路过的大佬指正。

组件开发流程

样式和动画

首先我们来考虑样式,对于message的调用我们下面再讲。

样式的话,无非就是实现一个这样消息弹出框,同时加上弹出时的动画,这里借助vuetransition来实现。

image.png

这些都是简单的内容,代码量很少我就直接贴在这里了。

<transition name="message-fade">
<div class="message"><p class="message-content"></p>
</div>
</transition>.message {position: fixed;top: 20px;left: 50%;z-index: 50;box-sizing: border-box;display: flex;align-items: center;padding: 15px 15px 15px 20px;overflow: hidden;background-color: #f0f9eb;border: 1px solid #ebeef5;border-radius: 5px;transition: opacity 0.3s, transform 0.4s, top 0.4s;transform: translateX(-50%);
}
.message-fade-enter-active,
.message-fade-leave-active {opacity: 0;transform: translate(-50%, -100%);
}.message-content {color: #67c23a;font-size: 14px;margin: 0;
}

当然现在这个message是只有空壳一样的内容,我们需要实现的效果是,有一个message函数接口,我们可以调用这个接口后弹出这个消息框。这其实就是和其它一些组件不太一样的地方,他的实现更倾向于一个接口函数一样。

写一个函数当然不是问题,问题是怎么实现调用函数后渲染我们的消息框出来。

这里就需要了解一下vue中渲染DOM的知识点了。

h函数和render函数

vue中,很多文件的开发都是在.vue文件的,这种文件开发是分为三大块来写,可以像类似写HTML时的感觉,这也是vue的卖点之一,让新手更易于上手。

但是我们要知道,.vue实际上也是需要通过一些打包工具来编译成js代码才能执行。

h函数就是把.vue中的代码编辑成一个虚拟DOM,最终会把template解析为render函数返回虚拟DOM,这点可以在Vue Dev Tools中看到:
image.png

也就是说,h函数是负责创建虚拟DOMrender是负责把这个虚拟DOM返回出去

接口函数

通过上面的介绍,大概不难猜出这个接口函数应该如何实现了,其实就是创建一个虚拟DOM出来包裹住我们的message组件,在利用render函数渲染出来即可。

import element from "./message.vue";
import { createVNode, render } from "vue";export default function message(options) {if (typeof options === "string") {options = {message: options as string,};}const params = {...options,};// vue2 的写法// new Vue(render:() => createVNode(element)).mount();const div = document.createElement("div"); // 创建一个divconst vnode = createVNode(element, params);  // 创建一个message组件的虚拟DOMrender(vnode, div); // 渲染虚拟DOMdocument.body.appendChild(div.firstElementChild); // 加入到body中
}

那我们既然可以调用message接口函数了,那么在message组件中还有一些逻辑需要实现——在执行结束后关闭掉弹出来的消息框。

这里就是利用v-show控制开关消息框,用定时器回调来解决关闭,我们可以利用props接收存在时间duration,这样我们的基本功能就算完成了,但是message组件还存在很多细节可以补充。

// message.vue
<transition name="message-fade"><div class="message" v-show="visible"><p class="message-content">{{ message }}</p></div>
</transition>const visible = ref(false);
let timer = null;
const start = () => {visible.value = true;if (timer !== null) {clearTimeout(timer);}if (props.duration > 0) {timer = setTimeout(() => {visible.value = false;}, props.duration);}
};onMounted(() => {start();
});onUnmounted(() => {if (timer !== null) {clearTimeout(timer);}
});

回调删除节点的性能优化

在刚刚上面完成的组件中,会发现当我们多次触发了message后,哪怕duration过了,节点也依然存在在body中,这些节点只是被隐藏了,并没有随着持续时间结束后删除掉。

image.png

这样显然是不太合理的,并且操作多了会存在一些性能问题,因此我们需要在这个组件在持续时间结束后可以被删除掉。

这里我们可以在动画结束后,派发出一个destroy事件

 <transition name="message-fade" @after-leave="$emit('destroy')"> // 派发删除操作<div class="message" v-show="visible"><p class="message-content">{{ message }}</p></div></transition>

这个$emit('destroy')会调用我们传进来的props中的onDestroy函数

// message.tsconst div = document.createElement("div");
const vnode = createVNode(element, params);
+ vnode.props.onDestroy = () => { // 在参数props中挂载销毁函数
+    render(null, div); // 利用render移除div节点
+ };
render(vnode, div);
document.body.appendChild(div.firstElementChild);

连续多次弹出的用户体验优化

当我们连续触发多次message时,会弹出多个消息,对于这多个消息,我们不希望会重叠在一起发生覆盖的情况,我们希望的是可以像下面这样。

image.png

那我们如何实现上面的效果呢?

我们可以在props中加一个offset属性,该属性为message组件的离视屏顶部的距离。

然后我们还需要知道上个节点的距离是多少,因此我们需要把连续点出的节点都记录起来,具体来说就是用一个数组把他们存起来,数组中的值按上一节点的offset基础上加合适的距离即可。

// message.ts+ const instances: VNode[] = [];
export default function message(options) {...+  let offset = options.offset || 20;+  instances.forEach((vnode: VNode) => {
+    offset += vnode.el.offsetHeight + 20;
+  });const params = {...options,
+    offset,};const div = document.createElement("div");const vnode = createVNode(element, params);vnode.props.onDestroy = () => {render(null, div); // render会移除dom,注意:此方法在vue2中无法使用
+   instances.pop();};render(vnode, div);document.body.appendChild(div.firstElementChild);
+  instances.push(vnode);
}

同时,我们需要在渲染出message组件中,加上新的offset位置。

// message.vue<transition name="message-fade" @after-leave="$emit('destroy')"><div class="message" v-show="visible" :style="topStyle"> // 更改top位置<p class="message-content">{{ message }}</p></div>
</transition>const topStyle = computed(() => {return {top: `${props.offset}px`,};
});

演示demo

完整项目demo

结语

Message组件的核心开发功能就是上面这些,其他更多的详细功能开发可以参考Hview-ui项目源码

如果想要了解更多的组件轮子开发,或者组件库开发流程,更多详细的组件开发过程更新在GitHub项目源码,最后觉得我们项目or文章不错可以点个star,点点小手支持一下,也欢迎各路大佬为我们的开源项目添砖加瓦。

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

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

相关文章

算法刷题记录-其他类型(LeetCode)

57 57. Insert Interval 思路 模拟 用指针去扫 intervals&#xff0c;最多可能有三个阶段&#xff1a; 不重叠的绿区间&#xff0c;在蓝区间的左边有重叠的绿区间不重叠的绿区间&#xff0c;在蓝区间的右边 逐个分析 不重叠&#xff0c;需满足&#xff1a;绿区间的右端&…

JVM之堆和方法区

目录 1.堆 1.1 堆的结构 1.1.1 新生代&#xff08;Young Generation&#xff09; 1.1.2 年老代&#xff08;Old Generation&#xff09; 1.1.3 永久代/元空间&#xff08;Permanent Generation/Metaspace&#xff09; 1.2 堆的内存溢出 1.3 堆内存诊断 1.3.1 jmap 1.3.2…

HTML5-3-表格

文章目录 属性边框属性标题跨行和跨列单元格边距 HTML 表格由 <table> 标签来定义。 tr&#xff1a;tr 是 table row 的缩写&#xff0c;表示表格的一行。td&#xff1a;td 是 table data 的缩写&#xff0c;表示表格的数据单元格。th&#xff1a;th 是 table header的缩…

黑盒测试中的决策表设计

前言 在软件开发中&#xff0c;测试是不可或缺的一个环节。其中&#xff0c;黑盒测试是一种比较常用的测试方法。它强调测试人员不需要知道程序内部结构&#xff0c;只需根据程序规格说明书来设计测试用例进行测试。本文将介绍黑盒测试中的一种决策表设计方法。 同时&#xf…

Games202(P6、P7)环境光照与PRT全局光照

P6、实时环境光照 RealTime Environment Mapping 不同于全局光照 (1) IBL 我的Blog&#xff1a; QT with OpenGL&#xff08;IBL-漫反射辐照&#xff09;IBL-镜面反射&#xff08;预滤波篇&#xff09;IBL-镜面反射&#xff08;LUT篇&#xff09;QT with OpenGL(IBL-镜面反…

mongodb数据库操作

1、启动mongodb /usr/local/mongodb/bin/mongod --dbpath /var/mongodb/data/--logpath /var/mongodb/logs/log.log &在mongodb启动命令中 --dbpath 指定mongodb的数据存储路径 --logpath 指定mongodb的日志存储路径 2、停止mongodb 第一步先进入mongo命令行模式 第二…

2023,软件测试人的未来在哪里?

2023年&#xff0c;IT行业出现空前的萧条&#xff0c;首先是年初一开始各大厂像着了魔似的不约而同的纷纷裁员、降薪、奖金包缩水&#xff0c;随之而来的是需求萎缩&#xff0c;HC减少或封锁等等。 而有幸未被列入裁员名单的在职人员&#xff0c;庆幸之余也心有余悸&#xff0…

R语言随机波动模型SV:马尔可夫蒙特卡罗法MCMC、正则化广义矩估计和准最大似然估计上证指数收益时间序列...

全文链接&#xff1a;http://tecdat.cn/?p31162 最近我们被客户要求撰写关于SV模型的研究报告&#xff0c;包括一些图形和统计输出&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 相关视频 本文做SV模型&#xff0c;选取马尔可夫蒙特卡罗法(MCMC)、正则化广…

App线上网络问题优化策略

在我们App开发过程中&#xff0c;网络是必不可少的&#xff0c;几乎很难想到有哪些app是不需要网络传输的&#xff0c;所以网络问题一般都是线下难以复现&#xff0c;一旦到了用户手里就会碰到很多疑难杂症&#xff0c;所以对于网络的监控是必不可少的&#xff0c;针对用户常见…

打字侠:一款专业的中文打字网站

打字侠第一个正式版发布啦&#xff01;&#xff01;&#xff01; 虽然离期望的样子还有一段路要走&#xff0c;不过能看到它正式发布&#xff0c;我还是很激动哟&#xff01; 打字侠是一款面向中学生和大学生的在线打字软件&#xff0c;它通过合理的课程设计和精美的图形界面帮…

力扣接雨水(解析)

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图&#xff0c;计算按此排列的柱子&#xff0c;下雨之后能接多少雨水。 示例 1&#xff1a; 输入&#xff1a;height [0,1,0,2,1,0,1,3,2,1,2,1] 输出&#xff1a;6 解释&#xff1a;上面是由数组 [0,1,0,2,1,0,1,3,2,1,2,1] …

【狂神】SpringMVC笔记(一)之详细版

1.Restful 风格 概念&#xff1a; 实现方式&#xff1a; 使用PathVariable 在url相同的情况下&#xff0c;会根据请求方式的不同来执行不同的方法。 使用RestFull风格的好处&#xff1a;简洁、高效、安全 2、接受请求参数及数据回显 2.1、请求参数 方式一&#xff1a;这里…

FFmpeg入门之简单介绍

FFmpeg是什么意思: Fast Forward Moving Picture Experts Group ffmpeg相关文档: Documentation FFmpeg ffmpeg源码下载: https://git.videolan.org/git/ffmpeg.git https://github.com/FFmpeg/FFmpeg.git FFmpeg能做什么? 多种媒体格式的封装与解封装 : 1.多种音…

基于SSM的家居商城系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

MySQL基础与库的基本操作

目录 1 MySQL基础一种存储解决方案SQL分类查看MySQL存储引擎 2 MySQL 库的操作数据库基本增删认识系统编码校验规则对数据库的影响数据库的查看与删除修改数据库数据库的备份与恢复查看连接情况 1 MySQL基础 一种存储解决方案 mysql本质是一种网络服务 mysql – 数据库服务的…

Stable DIffusion系统教程 | 局部重绘,增删修改的魔法棒

目录 1. 基本操作 1.1 步骤1 补充提示词 1.2 步骤2 绘制蒙版 1.3 步骤3 参数设置 2.局部重绘其他应用 2.1 手绘蒙版 2.2 删除某些东西 之前我们熟悉了AI绘画的各类模型&#xff0c;提示词写法&#xff0c;图像放大等技巧。但我们目前所有的操作都是针对整张图片的。 但…

栈的压入、弹出序列

⭐️ 题目描述 &#x1f31f; OJ链接&#xff1a;栈的压入、弹出序列 思路&#xff1a; 我们使用一个栈来模拟题目所给的压入、和弹出序列&#xff0c;若模拟成功则是真&#xff0c;模拟失败返回假。我们可以每次先从 pushV 入栈一个元素&#xff0c;在判断当前栈顶元素和 pop…

企业架构LNMP学习笔记10

1、Nginx版本&#xff0c;在实际的业务场景中&#xff0c;需要使用软件新版本的功能、特性。就需要对原有软件进行升级或重装系统。 Nginx的版本需要升级迭代。那么如何进行升级呢&#xff1f;线上服务器如何升级&#xff0c;我们选择稳定版本。 从nginx的1.14版本升级到ngin…

pprof火焰图性能优化

pprof火焰图性能优化 火焰图&#xff08;flame graph&#xff09;是性能分析的利器,在go1.1之前的版本我们需要借助go-torch生成,在go1.1后go tool pprof集成了此功能,今天就来说说如何使用其进行性能优化 在你启动http server的地方直接加入导入: _ “net/http/pprof” 获取…

zabbix监控H3C设备

背景 常见的服务和主机已经使用Prometheus进行监控了&#xff0c;但是网络设备还未配置监控。使用基于SNMP对网络设备进行监控。 设备概览 主要类型为H3C的路由器和交换机。H3CS5560交换机 路由器MER5200 er8300 步骤 配置网络设备开启telnet远程&#xff1b; 配置启用sn…