今天在全域性使用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 doing
Message(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一次就好啦
本文研究的還不算深入,只是單純的解決了一下遇到同樣問題的童鞋,也淺談了一下原理。有興趣的同學可以自行看看原始碼~~
逼就裝到這裡了,告辭~