热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

vue改变table某一行的值_Vue后台项目中遇到的技术难点以及解决方案

作者:yeyan1996转发链接:https:juejin.impost5c76843af265da2ddd4a6dd0写在前面金三银四招聘时间已经过去
ffce1ad20b37ed72f1121738a9f1f31c.png

作者:yeyan1996

转发链接:https://juejin.im/post/5c76843af265da2ddd4a6dd0

写在前面

金三银四招聘时间已经过去,很多公司开启了今年第二轮招聘的热潮,虽说今年是互联网的寒冬,但是只要对技术始终抱有热情以及有过硬的实力,即使是寒冬也不会阻挠你前进的步伐。在面试的时候,往往在二面,三面的时面试官会结合你的简历问一些关于你简历上项目的问题,而以下这个问题在很多时候都会被问到

在这个项目中你有遇到什么技术难点,你是怎么解决的?

其实这个问题旨在了解你在遇到问题的时候的解决方法,毕竟现在前端技术领域广,各种框架和组件库层出不穷,而业务需求上有时纷繁复杂,观察一个程序员在面对未知问题时是如何处理的,这个过程相对于只出一些面试题来考面试者更能了解面试者实际解决问题的能力

而很多人会说我的项目不大,并没有什么难点,或者说并不算难点,只能说是一些坑,只要google一下就能解决,实在不行请教我同事,这些问题并没有困扰我很久。其实我也遇到过相同的情况,和面试官说如何通过搜索引擎解决这些坑的吧不太好,让面试官认为你只是一个API Caller,但是又没有什么值得一谈的项目难点

我的建议是,如果没有什么可以深聊的技术难点,不妨在日常开发过程中,试着封装几个常用的组件,同时尝试分析项目的性能瓶颈,寻找一些优化的方案,同样也能让面试官对你有一个整体的了解

在这篇文章中,我会分享在我目前公司的项目里,是如何在满足业务需求的基础上,让整个系统焕然一新的过程

技术栈是Vue + Element的单页面应用

起源

在我刚入职的那会,编码能力不怎么好,加上之前离职的前端技术栈是React,接手这个Vue项目的时候,代码高度的耦合,而那个时候因为能力有限,也只是在他的基础上继续开发,好在接手的时候开发进度也只是刚刚开始,因此在几个月后的某一天,我做了一个决定:准备把整个项目重写

得益于整个后台管理系统都是我独立开发的,项目的不足点我都深有体会,并且修改的时候能够更加的自由,恰好在那段时间看了花裤衩的vue-element-admin,我决定新开一个工程把之前的代码全部重写

项目结构

之前我有打算基于Webpack4自己写个脚手架用来打包文件,但是那段时间刚好Vue-cli3刚刚发布正式版并且也是基于Webpack4封装的,于是想了一下还决定使用新的Vue-cli3脚手架搭建,最后我将项目分为以下层级

├─api //api接口├─assets //项目运行时使用到的图片和静态资源├─components //组件│ ├─BaseEllipsis //业务组件 (Base开头都是全局组件)│ ├─BasePagination //分页器组件 │ ├─BaseIcon //svg图标组件│ ├─BaseToggle //业务组件│ ├─BaseTable //表格组件│ ├─FormPanel //业务组件(Form开头是围绕表单相关的小组件)│ ├─TableOptions //业务组件(Table开头是围绕表格相关的小组件)│ ├─TheBreadcrumb //面包屑组件(The开头是每个页面组件只会引入一次的无状态组件)| ├─TheSidebar //侧边栏组件│ ├─TransitionSildeDown //业务组件(Transition开头是动画组件)│ └─index.js //全局组件自动注册的脚本│ ├─directives //自定义指令├─element //elementui├─errorLog //错误捕获├─filters //全局过滤器├─icons //svg图标存放文件夹├─interface //TypeScript接口├─mixins //局部混入├─router //vue-router│ ├─modules │ └─index.js ├─store //vuex│ ├─modules │ └─index.js ├─style //全局样式/局部页面可复用的样式├─util //公共的模块(axios,COOKIE封装,工具函数)├─vendor //类库文件└─views //页面组件(所有给用户显示的页面)

一个良好的项目分层在业务迭代的时候能够快速找到对应的模块进行修改,而不是在茫茫的代码海中找到其中的某一行代码

性能优化

在我重写整个系统之前,每次打包都会花费好几分钟的时间,并且打包后的项目超过了17M

ffd4b71d97c7ff3c72834aa2cbb6d668.png

然而在我优化系统之后,打包后的体积只有2M,缩小了8倍

d042bdd0ca805da728782ba77cae7795.png

这里我从以下4个方面分享一下我在项目中是如何改善系统的性能,让系统"步履如飞"的

  • 网络请求相关
  • 构建相关
  • 静态资源优化
  • 编码相关

网络请求相关

这部分旨在实现需求的前提下尽量减少http请求的开销,或者减少响应时间

CDN

将第三方的类库放到CDN上,能够大幅度减少生产环境中的项目体积,另外CDN能够实时地根据网络流量和各节点的连接、负载状况以及到用户的距离和响应时间等综合信息将用户的请求重新导向离用户最近的服务节点上

另外因为CDN和服务器的域名一般不是同一个,可以缓解同一域名并发http请求的数量限制,有效分流以及减少多余的COOKIE的发送(CDN上面的静态资源请求时不需要携带任何COOKIE)

通俗的来说就是使用CDN会一定程度上提升项目中的静态文件的传输速度,在vue-cli3中可以通过externals配置项,将第三方的类库的引用地址从本地指向你提供的CDN地址

externals只适用于ES Module的默认导入

b8ce0fcc81d69ddd87e1ebc8cee4b50f.png

这里通过环境变量来判断生产环境才启用CDN,除了需要开启CDN外,你还需要在index.html注入CDN的域名,所以我这里通过html-webpack-plugin根据cdn域名动态的注入script标签,同时需要在index.html中通过模版的语法声明循环的数组和注入的元素

打包前的index.html:

2be262ffc0aff0c0d9f3b35e529ddb9b.png

打包后的index.html:

fc10e15446a5c454f679a0bb20d196e4.png

可以看到通过这个插件可以将cdn域名动态的注入到打包后的index.html中

还有一点要注意的是,externals对象的属性为你引入包的名字,而属性值是对应的全局变量名称(CDN引入的类库文件会自动挂载到window对象下面,而挂载时的属性名需要去对应的CDN在源码中寻找,一般在开头行都会有声明,除此之外导入还有困难的还可以看下这篇博客webpack externals 深入理解)

7937430b61a73958577de4bdb65d06fa.png

这里还是建议尽量放到公司专用的CDN上,不推荐使用公共的CDN,因为容易挂,生产环境还是以稳定为主吧

合理的缓存策略

将长时间不会改变的第三方类库或者静态资源设置为强缓存,将max-age设置为一个非常长的时间,再将访问路径加上哈希达到哈希值变了以后保证获取到最新资源(vue-cli3会自动构建,自己搭建的webpack脚手架需要自行配置contentHash,chunkHash)

CDN上的缓存策略,可以看到max-age的值非常大,这样下次访问就只会读取本地磁盘/内存中缓存的资源:

753bfb7a1ff8b3b403e43a812155648d.png

对于index.html和一些图片等多媒体资源,可以选择协商缓存(max-age<&#61;0,Last-Modified,ETag),保证返回服务器最新的资源

一个好的缓存策略,有助于减轻服务器的压力,并且显著的提升用户的体验

gzip

为你的文件开启gzip压缩是一个不错的选择&#xff0c;通常开启gzip压缩能够有效的缩小传输资源的大小&#xff0c;如果你的项目是用nginx作为web服务器的话&#xff0c;只需在nginx的配置文件中配置相应的gzip选项就可以让你的静态资源服务器开启gzip压缩

#开启和关闭gzip模式 gzip on; #gizp压缩起点&#xff0c;文件大于1k才进行压缩 gzip_min_length 1k; # gzip 压缩级别&#xff0c;1-9&#xff0c;数字越大压缩的越好&#xff0c;也越占用CPU时间 gzip_comp_level 6; # 进行压缩的文件类型。 gzip_types text/plain application/Javascript application/x-Javascript text/css application/xml text/Javascript ; #nginx对于静态文件的处理模块&#xff0c;开启后会寻找以.gz结尾的文件&#xff0c;直接返回&#xff0c;不会占用cpu进行压缩&#xff0c;如果找不到则不进行压缩 gzip_static on # 是否在http header中添加Vary: Accept-Encoding&#xff0c;建议开启 gzip_vary on; # 设置gzip压缩针对的HTTP协议版本 gzip_http_version 1.1;

但是我们这里要说的是前端输出gzip文件&#xff0c;利用compression-webpack-plugin让webpack在打包的时候输出.gz后缀的压缩文件

ccac880989530c267a1792792ccede59.png
208b550f240af9b46de8ebff0964533a.png

这样不需要服务器主动压缩我们就已经可以得到gzip文件&#xff0c;在上面的nginx配置项中可以发现这一行

#nginx对于静态文件的处理模块&#xff0c;开启后会寻找以.gz结尾的文件&#xff0c;直接返回&#xff0c;不会占用cpu进行压缩&#xff0c;如果找不到则不进行压缩 gzip_static on

只要把.gz的文件放到服务器上&#xff0c;开始gzip_static就可以让服务器优先返回.gz文件&#xff0c;在面对高流量时&#xff0c;也能一定程度减轻对服务器的压力&#xff0c;属于用空间来换时间(.gz文件会额外占有服务器的空间)

资源嗅探

对于现代浏览器来说&#xff0c;可以给link标签添加preload,prefetch,dns-prefetch属性

preload

对于SPA应用来说,当浏览器解析完script脚本才会生成DOM节点,如果你的项目中没有使用服务端渲染的话且需要加载一个比较耗时的首屏图片时,可以考虑将这个首屏图片放在preload标签中让浏览器预先请求并加载执行,这样当script脚本执行完毕后就会瞬间加载图片(否则需要等脚本执行完毕后再向后台请求图片)

另外使用preload预加载首屏需要的css样式也是一个不错的选择,类似的库有critical

没有使用preload

cf3cf06800d408484749bde9287e7857.png

使用preload

c3c088a65c2c0841fc83b0d511524e44.png

通过Waterfall可以看到这个webp图片需要等到脚本加载完之后才回去请求,如果这个图片比较大就会浪费不必要的时间

在工程中&#xff0c;利用一些preload的webpack插件可以很方便的给打包后的index.html注入预加载的资源标签&#xff0c;有兴趣的朋友可以试着搜索一下相关的插件

prefetch

prefetch可以让浏览器提前加载下个页面可能会需要的资源,vue-cli3默认会给所有懒加载的路由添加prefetch属性&#xff0c;这样可以在你访问使用到懒加载的路由页面时能够获得更快的加载速度

preload和prefetch的区别在于&#xff0c;preload的资源会和页面需要的静态资源并行加载&#xff0c;而prefetch则会等到浏览器加载完必要的资源后&#xff0c;在空闲时间加载被标记为prefetch的资源

dns-prefetch

dns-prefetch可以让浏览器提前对域名进行解析&#xff0c;减少DNS查找的开销,如果你的静态资源和后端接口不是同一个服务器的话&#xff0c;可以将考虑你后端的域名放入link标签加入dns-prefetch属性

京东首页也使用到了dns-prefetch技术

3edb597e98c697955c6154eefb84f331.png

http2

http2从2015年问世以来已经走过了4个年头&#xff0c;如今在国内也有超过50%的覆盖率&#xff0c;得益于http2的分帧传输&#xff0c;它能够极大的减少http(s)请求开销

http2和http1.1的性能差异对比

如果系统首屏同一时间需要加载的静态资源非常多&#xff0c;但是浏览器对同一域名的tcp连接数量是有限制的(chrome为6个)超过规定数量的tcp连接&#xff0c;则必须要等到之前的请求收到响应后才能继续发送&#xff0c;而http2则可以在一个tcp连接中并发多个请求没有限制&#xff0c;在一些网络较差的环境开启http2性能提升尤为明显

这里极力推荐在支持https协议的服务器中使用http2协议,可以通过web服务器Nginx配置&#xff0c;或是直接让服务器支持http2

nginx开启http2非常简单,在nginx.conf中只需在原来监听的端口后面加上http2就可以了,前提是你的nginx版本不能低于1.95&#xff0c;并且已经开启了https

listen 443 ssl http2;

在network中通过protocol可以查看到当前的资源是通过哪个版本的http协议传输的

h2代表http2

b65d72022d5baaeb886d71f61ea63a6e.png

构建相关

构建方面通过合理的配置构建工具&#xff0c;达到减少生产环境的代码的体积&#xff0c;减少打包时间&#xff0c;缩短页面加载时间

路由懒加载

传统的路由组件是通过import静态的打包到项目中&#xff0c;这样做的缺点是因为所有的页面组件都打包在同一个脚本文件中&#xff0c;导致生产环境下首屏因为加载的代码量太多会有明显的卡顿(白屏)

通过import()使得ES6的模块有了动态加载的能力&#xff0c;让url匹配到相应的路径时&#xff0c;会动态加载页面组件&#xff0c;这样首屏的代码量会大幅减少&#xff0c;webpack会把动态加载的页面组件分离成单独的一个chunk.js文件

9a24eca41bda2d8cadcc9fce5ed3340a.png
7f1a3db4f06560d32ffc453f5b0c3845.png

当然懒加载也有缺点&#xff0c;就是会额外的增加一个http请求&#xff0c;如果项目非常小的话可以考虑不使用路由懒加载

预渲染

由于浏览器在渲染出页面之前&#xff0c;需要先加载和解析相应的html,css和js文件&#xff0c;为此会有一段白屏的时间&#xff0c;如何尽可能的减少白屏对用户的影响&#xff0c;目前我选择的是在html模版中&#xff0c;注入一个loading动画&#xff0c;这里我拿D2-Admin中的loading动画举例

很抱歉&#xff0c;如果没有 Javascript 支持&#xff0c;D2Admin 将不能正常工作。请启用浏览器的 Javascript 然后继续。

正在加载资源
初次加载资源可能需要较多时间 请耐心等待

在打包完成后&#xff0c;在这个index.html下方还会注入页面的脚本&#xff0c;当用户访问你的项目时&#xff0c;脚本还没有执行&#xff0c;但是可以显示loading动画&#xff0c;因为它是直接注入在html中的&#xff0c;等到脚本执行完毕后&#xff0c;Vue会新生成一个app的节点然后将旧的同名节点删除&#xff0c;这样可以有效的过渡白屏的时间

loading动画只是一个让用户感知到你程序正在启动的效果&#xff0c;只是一个静态页面没有任何的功能

另外预渲染还可以使用服务端渲染(SSR)&#xff0c;通过后端输出一个首页的模版&#xff0c;或者使用骨架屏的方案&#xff0c;这里本人没有深入的了解过&#xff0c;有兴趣的朋友可以去实践一下

升级到最新的webpack版本

webpack4相对于webpack3来说在打包优化方面性能提升还是比较明显的&#xff0c;如果觉得自己配置脚手架比较复杂的话&#xff0c;可以使用vue-cli3来构建你的项目&#xff0c;同样是基于webpack4搭建的

DllPlugin

当没有一个稳定的CDN时&#xff0c;使用DllPlugin这个webpack插件同样可以将类库从业务代码中分离出去&#xff0c;其原理是预先将类库文件打包&#xff0c;随后创建一个关联表&#xff0c;在业务代码依赖第三方类库时&#xff0c;会直接去关联表中获取已经打包好的类库文件。这样做的好处在于因为业务代码会常常需要打包上线&#xff0c;而第三方类库基本不会改变&#xff0c;所以每次打包可以跳过这些类库文件&#xff0c;减少不必要的重复打包

DllPlugin是一个webpack内置的插件&#xff0c;无需安装&#xff0c;但是要让打包后的index.html注入这些打包后第三方类库&#xff0c;需要额外安装add-asset-html-webpack-plugin插件

当你需要在index.html中注入多个类库时&#xff0c;需要实例化多次add-asset-html-webpack-plugin&#xff0c;这里我们可以利用nodejs的fs模块&#xff0c;遍历DllPlugin打包后的目录&#xff0c;根据类库的数量决定需要生成多少个实例&#xff0c;非常的灵活&#xff0c;具体的配置项可以查看我底部的链接

合理使用第三方库

如果项目中有一些日期操作的需求&#xff0c;不妨将目光从moment转移到day&#xff0c;相对于笨重的moment&#xff0c;它只有2kb&#xff0c;day和moment的api完全一样&#xff0c;并且中文文档也比较友好

另外对于lodash这类的库如果只需要部分功能&#xff0c;则只要引入其中一部分&#xff0c;这样webpack在treeshaking后在生产环境也只会引入这一部分的代码

b0184be3dc6737235eee55a33f4163c9.png

对于UI库(element-ui)打包后的体积也会非常大&#xff0c;尽量使用按需加载&#xff0c;官方文档上也有详细教程

element-ui的压缩后的体积竟然是Vue的十倍

89485ecab01dce834ba5e0cac11f5d45.png

常用的路径创建文件别名

给常用的模块路径创建一个别名是一个不错的选择&#xff0c;可以减少模块查找时耗费的时间&#xff0c;项目越大收益也就越明显

vue-cli3中的配置和使用方法(webpack链式调用文档)

c2cdc10c83c7a235c5caf78e62887eb5.png

使用可视化工具分析打包后的模块体积

我通过webpack-bundle-analyzer这个插件在每次打包后能够更加直观的分析打包后模块的体积&#xff0c;再对其中比较大的模块进行优化

d83e5b677964837fe7331e6c438315d4.png

这是我在优化前的各模块体积:

b850c8883b28173233fadc2809bce95c.png

因为业务需求,要求前端导出pdf和excel文件,我这里引入了xlsx和pdf.js这2个包,但是打包后通过可视化工具发现光这2个文件就占了一半的项目体积,另外elementui和moment也非常的大

525ceae1d08d38213f9ecae2ba6d133a.png

这是优化后通过可视化工具观察到的各模块体积,通过将这些类库放到CDN上或者使用dllPlugin将类库和业务文件分离,可以看到没有明显特别大的模块了

静态资源优化

这部分旨在减少请求一些图片资源所造成的影响

图片懒加载

如果你的系统是一个偏展示的项目需要给用户展示大量图片&#xff0c;是否启用图片懒加载可能是你需要考虑的一个点&#xff0c;不在用户视野中的图片是没有必要加载的&#xff0c;图片懒加载通过让图片先加载成一张统一的图片&#xff0c;再给进入用户视野的图片替换真正的图片地址&#xff0c;可以同一时间减少http请求开销&#xff0c;避免显示图片导致的画面抖动&#xff0c;提高用户体验

下面我提供2种图片懒加载的思路&#xff0c;这2个方案最终都是用将占位的图片替换成真正的图片&#xff0c;然后给img标签设置一个自定义属性data-src存放真正的图片地址&#xff0c;src存放占位图片的地址

getBoundingClientRect

DOM元素包含一个getBoundingClientRect方法&#xff0c;执行该方法返回当前DOM节点相关的CSS边框集合

75fbc7c8375712de0ce91cb8317f93b0.png

其中有一个top属性代表当前DOM节点距离浏览器窗口顶部的高度&#xff0c;只需判断top值是否小于当前浏览器窗口的高度(window.innerHeight)&#xff0c;若小于说明已经进入用户视野&#xff0c;然后替换为真正的图片即可

另外使用getBoundingClientRect作图片懒加载需要注意3点

  1. 因为需要监听scroll事件&#xff0c;不停的判断top的值和浏览器高度的关系&#xff0c;请对监听事件进行函数节流
  2. 当屏幕首次渲染时&#xff0c;不会触发scroll事件&#xff0c;请主动调用一次事件处理程序&#xff0c;否则若用户不滚动则首屏的图片会一直使用懒加载的默认图片
  3. 当所有需要懒加载的图片都被加载完&#xff0c;需要移除事件监听&#xff0c;避免不必要的内存占用

IntersectionObserver

IntersectionObserver作为一个构造函数&#xff0c;传入一个回调函数作为参数&#xff0c;生成一个实例observer&#xff0c;这个实例有一个observe方法用来观察指定元素是否进入了用户的可视范围&#xff0c;随即触发传入构造函数中的回调函数

同时给回调函数传入一个entries的参数&#xff0c;记录着这个实例观察的所有元素的一些阈值信息(对象)&#xff0c;其中intersectionRatio属性表示图片进入可视范围的百分比&#xff0c;大于0表示已经有部分进入了用户视野

45a8aa5c20866d06565f5ce3292c0090.png

此时替换为真实的图片&#xff0c;并且调用实例的unobserve将这个img元素从这个实例的观察列表的去除

84466e04db77dfc1b8af167eb73af2e0.png

实例代码

对懒加载还有迷惑的同学我这里写了一个DEMO可以参考一下实现的方式源代码

结论

这2种的区别在于监听的方式&#xff0c;我个人更推荐使用Intersection Observer&#xff0c;因为通过监听scroll事件开销比较大&#xff0c;而让将这个工作交给另一个线程异步的去监听开销会小很多&#xff0c;但是它的缺点是一些老版本的浏览器可能支持率不高&#xff0c;好在社区有polyfill的方案

或者可以直接使用第三方的组件库vue-lazyload

使用svg图标

相对于用一张图片来表示图标&#xff0c;svg拥有更好的图片质量&#xff0c;体积更小&#xff0c;并且不需要开启额外的http请求&#xff0c;svg是一个未来的趋势&#xff0c;阿里的图标库iconfont支持导出svg格式的图标&#xff0c;但是在项目中需要封装一个支持svg的组件&#xff0c;具体封装的教程可以参考花裤衩的文章这里就不多赘述了手摸手&#xff0c;带你优雅的使用 icon,或者可以参考我的github

使用webp图片

webp图片最初在2010年发布&#xff0c;目标是减少文件大小&#xff0c;但达到和JPEG格式相同的图片质量&#xff0c;希望能够减少图片档在网络上的发送时间。webp图片无损比png图片无损的平均体积要小 20%~40%&#xff0c;并且图片质量用肉眼看几乎没什么差别

webp图片的缺点是兼容性并不是那么的好&#xff0c;在can l use 上查到webp图片的支持率并不是那么的理想。但是我们仍可以在支持webp图片的浏览器中使用它&#xff0c;而在不支持的浏览器提供png图片

f2e0668097e64b197ca0bd4b29c4eb95.png

这里需要使用到响应式图片,HTML提供了picture标签让我们可以在不同设备中使用不同的图片格式

MDN:

HTML 元素通过包含零或多个 元素和一个 元素来为不同的显示/设备场景提供图像版本。浏览器会选择最匹配的子 元素&#xff0c;如果没有匹配的&#xff0c;就选择 元素的 src 属性中的URL。然后&#xff0c;所选图像呈现在元素占据的空间中。

在工程中我们可以这样使用

f64f0c7ca7b791da18d407d6b0d4ad30.png

picture标签包裹2个source标签,一个提供webp图片,通过srcset属性让浏览器从上到下选择可以支持的图片格式,如果浏览器不支持webp图片会只使用第二个source,会回退到png图片,如果浏览器不支持picture标签,会使用底部的img标签,同样也会生成一个png图片

picture标签的浏览器支持率,相对于webp要好很多(注意底部的img标签无论如何都要有&#xff0c;否则就算支持webp图片也无法渲染出图片)

9bdcba4cbc0b2df852b45d79b5617cf5.png

压缩图片

对于一些png图片可能质量会非常的高&#xff0c;但是对于Web平台来说&#xff0c;用户可能并不care图片的画质问题&#xff0c;但是如果加载图片导致页面出现卡顿那就显得得不偿失了&#xff0c;我们可以考虑将一些画质较高的图片做压缩处理&#xff0c;我这里使用tinypng帮我压缩图片&#xff0c;同样能够保证在肉眼几乎分辨不出区别的情况下&#xff0c;提供一个体积较小的图片&#xff0c;如果有其他好的压缩软件也可以推荐给我

另外有一个图片压缩的 loader image-webpack-loader&#xff0c;在用户肉眼分辨不清的情况下一定程度上压缩图片

编码相关

编码这方面主要是减少对DOM的访问&#xff0c;减少浏览器的重排/重绘&#xff0c;访问DOM是非常昂贵的操作&#xff0c;因为会涉及到2个不同的线程交互(JS线程和UI渲染线程)并且DOM本身又是一个非常笨重的对象&#xff0c;这里给出几个建议

  • 如果有需要动态创建DOM的需求&#xff0c;可以创建一个文档碎片(DocumentFragment)&#xff0c;在文档碎片中操作因为不是在当前文档流不会引起重排/重绘&#xff0c;最后再一次性插入DOM节点
  • 避免频繁获取视图信息(getBoundingClientRect,clientWidth,offsetWidth),当发生重排/重绘操作时浏览器会维护一个队列&#xff0c;等到超过了最大值或过了指定时间(1000ms/60 &#61; 16.6ms)才会去清空队列一次性执行操作&#xff0c;这样可以节省性能&#xff0c;而获取视图信息会立刻清空队列执行重排/重绘
  • 高频的监听事件使用函数防抖/节流(可以使用lodash库的throttle函数&#xff0c;但是推荐先搞懂原理)
  • 特效可以考虑单独触发渲染层(CSS3的transform会触发渲染层)&#xff0c;动画可以使用绝对定位脱离文档流

开发过程中小技巧

使用require.context这个webpack的api可以避免每次引入一个文件都需要显式的用import导入&#xff0c;它可以扫描你指定的文件&#xff0c;然后全部导入到指定文件&#xff0c;可以用在

  • vue-router的路由自动导入
  • vuex的模块自动导入
  • svg图标的自动导入
  • 全局组件的自动导入

vuex&#xff1a;

53951b4aca72c88680c4dfd9a7ed78e8.png

这样在创建一个新的模块时,不需要在index.js中用import引入,在modules中再声明一遍了

全局组件和svg图标&#xff1a;

9eb364392aa3aabd43902407920fd4a4.png

避免了每创建一个全局组件都需要引入,再调用一次Vue.component的过程,而当加载到Svg组件会自动扫描icons文件夹,将所有svg图标导入进来

推荐Vue学习资料文章&#xff1a;

《手把手教你Electron &#43; Vue实战教程(一)》

《手把手教你Electron &#43; Vue实战教程(二)》

《手把手教你Electron &#43; Vue实战教程(三)》

《收集22种开源Vue模板和主题框架「干货」》

《如何写出优秀后台管理系统&#xff1f;11个经典模版拿去不谢「干货」》

《手把手教你实现一个Vue自定义指令懒加载》

《基于 Vue 和高德地图实现地图组件「实践」》

《一个由 Vue 作者尤雨溪开发的 web 开发工具—vite》

《是什么让我爱上了Vue.js》

《1.1万字深入细品Vue3.0源码响应式系统笔记「上」》

《1.1万字深入细品Vue3.0源码响应式系统笔记「下」》

《「实践」Vue 数据更新7 种情况汇总及延伸解决总结》

《尤大大细说Vue3 的诞生之路「译」》

《提高10倍打包速度工具Snowpack 2.0正式发布&#xff0c;再也不需要打包器》

《大厂Code Review总结Vue开发规范经验「值得学习」》

《Vue3 插件开发详解尝鲜版「值得收藏」》

《带你五步学会Vue SSR》

《记一次Vue3.0技术干货分享会》

《Vue 3.x 如何有惊无险地快速入门「进阶篇」》

《「干货」微信支付前后端流程整理(Vue&#43;Node)》

《带你了解 vue-next(Vue 3.0)之 炉火纯青「实践」》

《「干货」Vue&#43;高德地图实现页面点击绘制多边形及多边形切割拆分》

《「干货」Vue&#43;Element前端导入导出Excel》

《「实践」Deno bytes 模块全解析》

《细品pdf.js实践解决含水印、电子签章问题「Vue篇」》

《基于vue &#43; element的后台管理系统解决方案》

《Vue仿蘑菇街商城项目(vue&#43;koa&#43;mongodb)》

《基于 electron-vue 开发的音乐播放器「实践」》

《「实践」Vue项目中标配编辑器插件Vue-Quill-Editor》

《基于 Vue 技术栈的微前端方案实践》

《消息队列助你成为高薪 Node.js 工程师》

《Node.js 中的 stream 模块详解》

《「干货」Deno TCP Echo Server 是怎么运行的&#xff1f;》

《「干货」了不起的 Deno 实战教程》

《「干货」通俗易懂的Deno 入门教程》

《Deno 正式发布&#xff0c;彻底弄明白和 node 的区别》

《「实践」基于Apify&#43;node&#43;react/vue搭建一个有点意思的爬虫平台》

《「实践」深入对比 Vue 3.0 Composition API 和 React Hooks》

《前端网红框架的插件机制全梳理(axios、koa、redux、vuex)》

《深入Vue 必学高阶组件 HOC「进阶篇」》

《深入学习Vue的data、computed、watch来实现最精简响应式系统》

《10个实例小练习&#xff0c;快速入门熟练 Vue3 核心新特性(一)》

《10个实例小练习&#xff0c;快速入门熟练 Vue3 核心新特性(二)》

《教你部署搭建一个Vue-cli4&#43;Webpack移动端框架「实践」》

《2020前端就业Vue框架篇「实践」》

《详解Vue3中 router 带来了哪些变化&#xff1f;》

《Vue项目部署及性能优化指导篇「实践」》

《Vue高性能渲染大数据Tree组件「实践」》

《尤大大细品VuePress搭建技术网站与个人博客「实践」》

《10个Vue开发技巧「实践」》

《是什么导致尤大大选择放弃Webpack&#xff1f;【vite 原理解析】》

《带你了解 vue-next(Vue 3.0)之 小试牛刀【实践】》

《带你了解 vue-next(Vue 3.0)之 初入茅庐【实践】》

《实践Vue 3.0做JSX(TSX)风格的组件开发》

《一篇文章教你并列比较React.js和Vue.js的语法【实践】》

《手拉手带你开启Vue3世界的鬼斧神工【实践】》

《深入浅出通过vue-cli3构建一个SSR应用程序【实践】》

《怎样为你的 Vue.js 单页应用提速》

《聊聊昨晚尤雨溪现场针对Vue3.0 Beta版本新特性知识点汇总》

《【新消息】Vue 3.0 Beta 版本发布&#xff0c;你还学的动么&#xff1f;》

《Vue真是太好了 壹万多字的Vue知识点 超详细!》

《Vue &#43; Koa从零打造一个H5页面可视化编辑器——Quark-h5》

《深入浅出Vue3 跟着尤雨溪学 TypeScript 之 Ref 【实践】》

《手把手教你深入浅出vue-cli3升级vue-cli4的方法》

《Vue 3.0 Beta 和React 开发者分别杠上了》

《手把手教你用vue drag chart 实现一个可以拖动 / 缩放的图表组件》

《Vue3 尝鲜》

《总结Vue组件的通信》

《Vue 开源项目 TOP45》

《2020 年&#xff0c;Vue 受欢迎程度是否会超过 React&#xff1f;》

《尤雨溪&#xff1a;Vue 3.0的设计原则》

《使用vue实现HTML页面生成图片》

《实现全栈收银系统(Node&#43;Vue)(上)》

《实现全栈收银系统(Node&#43;Vue)(下)》

《vue引入原生高德地图》

《Vue合理配置WebSocket并实现群聊》

《多年vue项目实战经验汇总》

《vue之将echart封装为组件》

《基于 Vue 的两层吸顶踩坑总结》

《Vue插件总结【前端开发必备】》

《Vue 开发必须知道的 36 个技巧【近1W字】》

《构建大型 Vue.js 项目的10条建议》

《深入理解vue中的slot与slot-scope》

《手把手教你Vue解析pdf(base64)转图片【实践】》

《使用vue&#43;node搭建前端异常监控系统》

《推荐 8 个漂亮的 vue.js 进度条组件》

《基于Vue实现拖拽升级(九宫格拖拽)》

《手摸手&#xff0c;带你用vue撸后台 系列二(登录权限篇)》

《手摸手&#xff0c;带你用vue撸后台 系列三(实战篇)》

《前端框架用vue还是react&#xff1f;清晰对比两者差异》

《Vue组件间通信几种方式&#xff0c;你用哪种&#xff1f;【实践】》

《浅析 React / Vue 跨端渲染原理与实现》

《10个Vue开发技巧助力成为更好的工程师》

《手把手教你Vue之父子组件间通信实践讲解【props、$ref 、$emit】》

《1W字长文&#43;多图&#xff0c;带你了解vue的双向数据绑定源码实现》

《深入浅出Vue3 的响应式和以前的区别到底在哪里&#xff1f;【实践】》

《干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)》

《基于Vue/VueRouter/Vuex/Axios登录路由和接口级拦截原理与实现》

《手把手教你D3.js 实现数据可视化极速上手到Vue应用》

《吃透 Vue 项目开发实践&#xff5c;16个方面深入前端工程化开发技巧【上】》

《吃透 Vue 项目开发实践&#xff5c;16个方面深入前端工程化开发技巧【中】》

《吃透 Vue 项目开发实践&#xff5c;16个方面深入前端工程化开发技巧【下】》

《Vue3.0权限管理实现流程【实践】》

《后台管理系统&#xff0c;前端Vue根据角色动态设置菜单栏和路由》


作者&#xff1a;yeyan1996
转发链接&#xff1a;https://juejin.im/post/5c76843af265da2ddd4a6dd0



推荐阅读
  • <!DOCTYPEhtml><htmllang=en><head><metacharset=UT ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • Vue基础一、什么是Vue1.1概念Vue(读音vjuː,类似于view)是一套用于构建用户界面的渐进式JavaScript框架,与其它大型框架不 ... [详细]
  • 最近做项目时遇到一个问题,产品搜索后出来相关的列表,点击相关商品进入它的详情,返回后组件被重新创建,但产品需求是需要保留进入 ... [详细]
  • 写在前面因为业务关系,涉及到的新老业务较多。因此接触过webpack早期与后期的阶段。以及vue-cli2、3、4我们现在已经在使用vue-cli4了老生常谈的几个优 ... [详细]
  • vue使用
    关键词: ... [详细]
  • 本文详细介绍了cisco路由器IOS损坏时的恢复方法,包括进入ROMMON模式、设置IP地址、子网掩码、默认网关以及使用TFTP服务器传输IOS文件的步骤。 ... [详细]
  • 单页面应用 VS 多页面应用的区别和适用场景
    本文主要介绍了单页面应用(SPA)和多页面应用(MPA)的区别和适用场景。单页面应用只有一个主页面,所有内容都包含在主页面中,页面切换快但需要做相关的调优;多页面应用有多个独立的页面,每个页面都要加载相关资源,页面切换慢但适用于对SEO要求较高的应用。文章还提到了两者在资源加载、过渡动画、路由模式和数据传递方面的差异。 ... [详细]
  • 本文讨论了将HashRouter改为Router后,页面全部变为空白页且没有报错的问题。作者提到了在实际部署中需要在服务端进行配置以避免刷新404的问题,并分享了route/index.js中hash模式的配置。文章还提到了在vueJs项目中遇到过类似的问题。 ... [详细]
  • 一、路由首先需要配置路由,就是点击good组件进入goodDetail组件配置路由如下{path:goodDetail,component:goodDetail}同时在good组件中写入如下点击事件,路由中加入 ... [详细]
  • 翻译 | 编写SVG的口袋指南(上)
    作者:DDU(沪江前端开发工程师)本文是原文翻译,转载请注明作者及出处。简介ScalableVectorGraphics(SVG)是在XML中描述二维图形的语言。这些图形由路径,图 ... [详细]
  •     系统采用jeeplus框架(ssm+redis+shiro+mongodb+redis),默认是做了JSP未做前后端分离,由于业务需要已经多终端使用的需求(H5、小程序等) ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
author-avatar
n张家珲
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有