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"
      });
    },

结果:

image

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

代码分析

查看了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更新之后,在执行第二次通知的代码,此时通知的高度就会计算正确
如图:

image

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

推荐解决办法

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

data(){
    return {
     notifyPromise:Promise.resolve()   
    }
},
methods:{
    notify(){
        //通知,解决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条或任意多条通知显示都正常,如图:

image

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

tips

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

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

你可能感兴趣的:(element-ui Notification重叠问题,原因及解决办法)