element-ui Notification重叠问题,原因及解决办法(原文有部分错误,已订正)

场景

在1个方法中调用两次this.$notify方法,会出现通知框重叠的问题

代码

testNotify() {
      this.$notify({
        title: "提示",
        message: '1111',
        dangerouslyUseHTMLString: true,
        duration: 0,
        position: "bottom-right"
      });
      this.$notify({
        title: "提示",
        message: '2222',
        dangerouslyUseHTMLString: true,
        duration: 0,
        position: "bottom-right"
      });
    },
复制代码

结果:

 

 

 

第二个通知会覆盖到第一个通知上边,并没有隔开间距

代码分析

查看了notify的源码,找到了原因

  let verticalOffset = options.offset || 0;
  instances.filter(item => item.position === position).forEach(item => {
    verticalOffset += item.$el.offsetHeight + 16;
  });
  verticalOffset += 16;
  instance.verticalOffset = verticalOffset;
复制代码

计算通知的间距时,会取当前元素的高度 item.$el.offsetHeight ,但是因为vue的异步更新队列有缓冲机制,第一次方法调用时,并没有更新dom,导致取到的高度为0,所有第二个通知只是上移了默认的offset 16px,并没有加上第一个通知的高度 vue 异步更新队列文档

解决办法

有局限的解决办法

最简单的解决办法就是使用vue提供的nextTick方法,将上述代码改为如下:

    testNotify() {
      this.$notify({
        title: "提示",
        message: "1111",
        dangerouslyUseHTMLString: true,
        duration: 0,
        position: "bottom-right"
      });
      this.$nextTick(() => {
        this.$notify({
          title: "提示",
          message: "2222",
          dangerouslyUseHTMLString: true,
          duration: 0,
          position: "bottom-right"
        });
      });
    },
复制代码

第一次通知调用完之后,在nextTick的回调函数中执行第二次通知的调用,保证第一次通知的dom更新之后,在执行第二次通知的代码,此时通知的高度就会计算正确 如图:

 

 

 

这种解决方法有很大的局限性,实际业务场景中同时弹出的通知数量是不确定的,如果是三个、四个时该怎么写?回调函数套回调函数么??

推荐解决办法

由于对Promise理解的也不是很透彻,折腾了一下午算是想了个通用点的解决办法

data(){
    return {
     notifyPromise:Promise.resolve()   
    }
},
methods:{
       //通知,解决element-ui,同时调用notify时,通知重叠的问题
    notify(msg) {
          this.notifyPromise = this.notifyPromise.then(this.$nextTick).then(()=>{
            this.$notify({
              title: "提示",
              message: msg,
              dangerouslyUseHTMLString: true,
              duration: 0,
              position: "bottom-right"
            });
         })
    },
    testNotify(){
        this.notify(111);
        this.notify(222);
        this.notify(333);
        this.notify(444);
    }
}

注意:this.$nextTick()不传回调函数时返回的是个Promise

执行testNotify方法后,1条或任意多条通知显示都正常,如图:

 

 

 

如果哪位同学有更好的解决方法,请评论留言,谢谢

tips

本来想给element-ui提个issue,但是他们的github上要求在jsfiddle上创建重现的链接,但是我打不开jsfiddle的网站,只好作罢。。

哪位同学方便的话,请顺手提交一下issue,希望后续的版本能直接支持这种场景

 

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值