今天在全局使用Message组件的时候(单独使用import Message from 'element-ui'),发现第一次打开Message后再打开的Message无法关闭了,无论是使用showClose手动关闭还是通过duration来自动关闭,在第二次打开对应的组件的时候都无法关闭了,然而控制台也都没有报错
我的代码写法如下:
import { Message } from 'element-ui'const message_conf = { showClose: true, message: '网络出错啦...', type: 'error', duration: 2000}//... some fn doingMessage(message_conf)复制代码
根据官网给出的demo:
this.$message({ message: '居中的文字', center: true});单独引入 Message:import { Message } from 'element-ui';此时调用方法为 Message(options)。我们也为每个 type 定义了各自的方法,如 Message.success(options)。 并且可以调用 Message.closeAll() 手动关闭所有实例。复制代码
就是说可以在vm实例中通过this.$message(options)方法来调用出message,也可以通过在文件中单独引入Message,通过Message(options)来调用,而传入的options的配置都是相同的,因为我是在一个公用的server方法中写的Message,所以我想我是否可以放在vm实例中调用试一下呢,运行后发现,还是他么的不能关闭... what the mother fucker???
然后我再仔细看了一遍官网的调用:
this.$message({ message: '居中的文字', center: true});复制代码
他传入的options是一个新的object, 而我第二次传入的和第一次传入的options都是同一个对象——message_conf,会不会是这个问题呢。然后我尝试了一下把传入的message_conf改成和官网一样的
Message({ showClose: true, message: '网络出错啦...', type: 'error', duration: 2000})复制代码
果然这样就他么不会出幺蛾子了。。
然后我在第一次调用Message后,console.log了一下传入的message_conf,果然,值他么改变了:
不要问我为啥const 修饰的对象为啥会改变,因为const 修饰引用类型的数据 都是修饰的是他的引用而不是实际对应的属性值。
就意味着,第一次调用Message的时候将传入的message_conf的值改变了,然后第二次传入的message_conf就是第一次被修改后的值,那么问题就一定是出在传入的值上。 经过我呕心沥血的测试(其实就那么一两分钟),发现导致无法关闭的关键属性是closed,第一次调用Message后传入的message_conf多了一个属性closed:true,再第二次传入的时候将这个属性传入的话 那么无论如何都无法关闭了。
我猜想的话,element-ui notice组件判定是否关闭就是通过传入的closed来判定的,第一次传入的option不包含这个属性,那么内置会通过Object.assign添加一个closed: false的属性到传入的对象中,然后在timer时间到或者执行close()方法的时候将 closed属性变为true。
如果要用和我同样的写法的话解决方法就是讲传入的message_conf进行deepClone一次就好啦
本文研究的还不算深入,只是单纯的解决了一下遇到同样问题的童鞋,也浅谈了一下原理。有兴趣的同学可以自行看看源码~~
逼就装到这里了,告辞~