vue实现遮罩层,vue遮罩效果

  vue实现遮罩层,vue遮罩效果

  本文主要介绍如何在Vue项目中添加界面监控掩码。通过示例代码非常详细的介绍,对大家的学习或者工作都有一定的参考价值。有需要的朋友就跟着下面的边肖学习吧。

  

一、业务背景

  前端经常使用屏蔽层来屏蔽用户的异常操作。但在一些项目中,掩膜层没有统一管理,会造成以下问题:

  (1)所有业务组件都应该引入掩码层组件,即每个。vue业务组件在模板中引入了mask组件。组件存在于项目的各个角落,不利于管理,代码极其冗余。

  (2)遮罩组件分散在业务的各个角落,所以控制是否显示遮罩层的变量也分散在业务组件中。例如,当使用maskShow控制是否显示遮罩层时,一个更复杂的项目将生成一个maskShow变量200。

  (3)面具秀太多,融入商业。同时,mask shows的变量经常被写入接口的回调函数中,经常会出现忘记更改变量的情况,导致应该显示和不应该显示的mask图层出现逻辑错误。

  (4)项目经常在本地调试,但实际运行是在线的。(3)中的问题无法在本地验证。因为在线网络环境差的时候往往会出现这些问题。比如按下一个按钮后,需要等待界面返回后再点击。但是因为局部返回速度更快,所以如果忘记添加蒙版层也不会有问题。但如果是有网络问题的在线环境,就很容易出现,而且一旦出现问题,很难定位,大大影响工作效率。

  

二、问题分析

  根据以上背景,在实际项目中添加一个通用的遮罩层组件进行管理就变得非常有意义。经过分析,需要解决以下问题:

  (1)遮罩层出现和关闭的时机。

  (2)面罩组件设计。

  (3)如何优雅地将这个组件引入到项目中而不耦合。

  (4)如何在现有项目中逐步替换原有的maskShow,不至于造成大规模的问题。

  (5)细节。

  

三、组件设计

  

1、遮罩层出现和关闭的时机

  问题取决于不同的业务需求,但笔者认为大部分面具的出现和关闭主要取决于接口的请求和返回。当请求挂起时,一个接口显示遮罩层,所有接口返回并关闭遮罩。本文主要解决接口请求掩码的问题,是ts写的,不一一列举。

  

2、Mask组件设计

  Mask组件是一个类,它屏蔽了类内部的细节。

  (1)1)类内部的主要功能是添加和删除遮罩层,传输当前请求接口的url。

  类别掩码{

  //显示遮罩层

  appendMask(url: string): void{}

  //删除遮罩层

  removeMaskl(url: string): void{}

  }

  (2)添加一个mask layer函数,请求时调用,传入当前接口url。该函数在内部维护一个监听对象,用于监听当前是否有挂起的请求。此对象的值是此接口的挂起状态的数量。假设组件是通过mask视图挂载在Vue原型链上的,如果不是,就在组件上方引入。

  //监控对象数据类型定义

  接口HTTPDictInterface {

  【索引:字符串】:数字;

  }

  appendMask(url: string): void{

  如果(!this.monitorHTTPDict[url]){

  this . monitor httpdict[URL]=0;

  }

  this . monitor httpdict[URL]=1;

  //如果有监听接口,显示mask层。

  如果(!this . mask object . keys(this . monitorhttpdict)。长度){

  //在正文上添加蒙版图层样式,$Mask是蒙版图层样式组件。

  const Constructor=vue . extend(vue . prototype . $ Mask);

  this.mask=新构造函数()。$ mount();

  document . body . appendchild(this . mask . $ El);

  }

  }

  (3)删除mask layer函数,每次请求后都会调用,当发现请求的监听对象为空时,删除mask layer。如果没有处于挂起状态的接口,删除停靠键。如果对象是空的并且有一个遮罩层,请删除该遮罩层。

  removeMask(url: string): void{

  //成功返回后

  if(this . monitorhttpdict[monitor URL]){

  this . monitorhttpdict[monitor URL]-=1;

  if(this . monitorhttpdict[monitor URL]=0){

  删除this . monitorhttpdict[monitor URL];

  }

  }

  //hasMask用于检测页面上是否有Mask层标签元素。

  if (this.mask this.hasMask()!object . keys(this . monitorhttpdict)。长度){

  document . body . remove child(this . mask . $ El);

  this.mask=null

  }

  this.timer=null

  }

  

3、该组件如何优雅的引入到项目中,不产生耦合。

  使用这个组件,您需要在所有请求启动之前调用appendMask函数,在所有请求完成之后调用removeMask函数。有两种称呼。

  (1)利用axios等组件的回调来完成函数调用。但是这种方式并没有让Mask组件的代码独立于项目,而是依赖于具体接口框架的API。

  instance . interceptors . request . use((config)={

  //添加一个遮罩层

  mask . append mask(config . URL);

  返回配置;

  });

  (2)添加init函数,将回调直接注入原生XMLHttpRequest对象。更改本机XMLHttpRequest函数,并将回调注入事件“loadstart”和“loadend”。需要注意的是,loadstart接收的参数中没有当前请求的url,所以需要重写open函数,将open接收的参数的url挂载到新的xhr对象上。小心使用这种方法。因为改变原生API是非常危险的,所以在很多编码规范中都是禁止的。如果每个人都重写原生API,同时引入这些框架会导致冲突和意想不到的后果。

  //通过传递参数来决定是否使用此方法。

  init(){

  if (this.autoMonitoring){

  this . initrequestmonitor();

  }

  }

  //新的xmlhttprequest类型

  接口NewXhrInterface扩展了XMLHttpRequest{

  requestUrl?字符串

  }

  //本机注入

  initRequestMonitor(): void{

  设OldXHR=window。XMLHttpRequest

  让Mask class:Mask=this;

  //@ts-ignore,编码规范不允许修改XMLHttpRequest。

  窗户。XMLHttpRequest=function () {

  let realXHR:newxprinterface=new OldXHR();

  let old open:Function=realxhr . open;

  realXHR.open=(.参数:(string boolean undefined null)[]):void={

  realxhr . request URL=(args[1]as string);

  oldOpen.apply(realXHR,args);

  };

  real xhr . addevent listener(` load start ,()={

  const request URL:string=(realxhr . request URL为string);

  const URL:string=mask class . cleanbase URL(request URL);

  //打开面具

  mask class . append mask(URL);

  });

  real xhr . addevent listener(` loadend ,()={

  const response URL:string=(realXHR as XMLHttpRequest)。responseURL

  const URL:string=mask class . cleanbase URL(response URL);

  //删除掩码

  mask class . remove mask(URL);

  });

  返回realXHR

  };

  }

  (3)注入使用模式,直接调用init。这样,所有更改项目的请求都将通过掩码。

  新遮罩()。初始化()

  

4、如何在已有的项目中,渐进式的更换原有的maskShow的方式,从而不造成大面积问题。

  如果直接用在整个项目中,涉及的面会变得很广,大面积出现问题,反而得不偿失。因此,应采用渐进替换的方法实现平稳过渡。主要思想是通过配置页面和黑名单来决定将哪些页面引入这个组件,这样每个团队成员都可以自己修改。毕竟负责页面的人是最了解当前页面业务的人。至于怎么上黑名单还是白名单,由项目具体业务决定。

  //key需要监控的路由页面,值为一个数组,数组中填充的接口被列入黑名单,所以没有需要监控的接口。

  const PAGE _ ONE=`/home `;

  const PAGE _ TWO=`/log in `;

  const HTTO_ONE=`xxx

  出口常量maskUrlList={

  [第一页]: [HTTO第一页],

  [PAGE_TWO]: [],

  };

  AppendMask方法过滤黑名单和未配置的页面。MaskUrlList是受控对象。先检查页面路由,再检查是否有黑名单。

  appendMask(url: string): void{

  //获取当前页面的路径,获取页面路径,根据哈希和历史模式进行区分。

  const monitor path:string=this . getmonitorpath();

  //maskUrlList是一个配置项。先检查页面路由,再检查是否有黑名单。

  if(this . maskurlist[monitor path]

  !this . maskurlist[monitor path]。包括(url)) {

  if(this . monitorhttpdict[URL]===undefined){

  this . monitor httpdict[URL]=0;

  }

  this . monitorhttpdict[monitor URL]=1;

  }

  //添加一个遮罩层

  如果(!this . mask this . hasmonitorrul()){

  const Constructor=vue . extend(vue . prototype . $ Mask);

  this.mask=新构造函数()。$ mount();

  document . body . appendchild(this . mask . $ El);

  }

  }

  

5、细节问题

  (1)渲染后关闭遮罩层,将实际删除遮罩层的逻辑放入定时器。Vue的异步渲染采用的是promise,所以如果渲染后关闭,需要放入setTimeout。这涉及到事件周期的知识。当接口返回时,如果需要渲染页面,将异步执行一个Promise,Promise作为微任务,setTimeout作为宏任务。当主线程执行完毕后,首先执行微任务,然后执行异步宏任务setTimeout。

  //清理遮罩层

  如果(!this.timer) {

  this . timer=window . settimeout(()={

  if (this.mask this.hasMask()!this . hasmonitorrul()){

  document . body . remove child(this . mask . $ El);

  this.mask=null

  }

  this.timer=null

  }, 0);

  }

  (2)?过滤器接口的。在哈希模式下使用 # ,

  //获取请求接口的url

  getmonitorrul(URL:string):string {

  const URL index:number=URL . index of(`?`);

  let monitor URL:string=URL;

  if (urlIndex!==-1) {

  monitorUrl=url.substring(0,URL index);

  }

  返回monitorUrl

  }

  //获取当前路由路径

  getMonitorPath(): string{

  const path:string=this . mode===HASH _ TYPE?windows . location . hash:window . location . pathname;

  let monitor path:string=path;

  if (this.mode===HASH_TYPE) {

  monitor path=monitor path . substring(path . index of(`#`)1);

  }

  //截图路径,删除请求参数

  const hash index:number=monitor path . index of(`?`);

  if (hashIndex!==-1) {

  monitor path=monitor path . substring(0,hashIndex);

  }

  返回monitorPath

  }

  (3)接口过滤baseUrl。如果你细心的话,你会发现当你使用axios的界面时,你可以决定是否引入baseUrl。这是因为axios会区分和过滤请求。如果在项目前期没有很好的定义用法,那么axios会有两种不同的使用方式。然后,您需要过滤baseUrl。

  //删除baseUrl

  cleanbase URL(full URL:string):string {

  const base URL length:number=this . base URL . length;

  返回full URL . substring(base URL length);

  }

  (4)组件初始化,通过传入params实例化对象。

  新遮罩({

  类型,//哈希或历史记录

  AutoMonitoring,//要多写原生XMLHttpRequest对象吗?

  MaskUrlList,//配置引入的页面和接口。

  BaseUrl,//当前项目的基Url

  .

  }).初始化()

  

四、总结

  本文介绍了统一掩膜层的背景、问题和设计方案。但并没有列出所有的细节,需要根据实际业务来选择。但总的计划已经列出:

  (1)当部分界面待定时应显示mask层,所有界面返回时自动关闭。这里的接口是指被监控的接口。

  (2)组件最重要的两个功能是appendMask添加遮罩层和removeMask删除遮罩层。

  (3)如果想让Mask完全独立,又不想依赖第三方库(axios)的回调,可以直接重写XMLHttpRequest,但这样有风险,不推荐。

  (4)组件替换统一了团队成员自己配置路由和监控接口的方式。这里的逻辑可以自己决定。如果要监控的接口很多,可以用黑名单,反之,可以用白名单。

  (5)对渲染、请求参数和路由方式进行了优化。

  关于如何在Vue项目中添加接口监控mask的这篇文章到此为止。更多关于Vue接口监控屏蔽的信息,请搜索我们之前的文章或者继续浏览下面的相关文章。希望大家以后能多多支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: