[Vue源碼分析]谷歌翻譯後,Vue雙向數據綁定失效了?

前言:

最近運營反饋了一個問題:谷歌瀏覽器打開第三方儲值平臺,使用谷歌瀏覽器自帶的翻譯功能後,選擇商品沒有計算總額。
首先可以肯定的是這不是bug,這個平臺已經兼容了13種語言,只是運營沒有通過語言欄切換語言,而是通過谷歌翻譯。
當初想到的方法禁止谷歌瀏覽器翻譯當前頁面,如下:(已採用)

<meta name="google" content="notranslate">

但站在技術的角度來說,看看爲什麼還是有必要的,儲值平臺基於Vue,計算總額應用了雙向數據綁定;爲什麼谷歌翻譯後,Vue雙向數據綁定失效?真的是失效了嗎?接下來我們以最簡單的例子還原案發現場,順便解讀一下這部分相關Vue源碼。

問題重現

如下圖,實現簡單的雙向數據綁定,name初始化爲test:
在這裏插入圖片描述
在這裏插入圖片描述
刷新瀏覽器,將當前頁面翻譯成中文,如下圖:
在這裏插入圖片描述
翻譯後再次輸入,下邊沒有更新輸入的內容。
在這裏插入圖片描述

源碼分析

首先自信地排除這是業務代碼的bug,然後我們自信地看看框架相關部分的源碼。

瀏覽器翻譯前

可以看到,瀏覽器翻譯前,當輸入新的數據,這個文本節點的新舊虛擬DOM會進行對比;text不一樣時會執行setTextContent方法,如下如所示。
在這裏插入圖片描述在這裏插入圖片描述
setTextContent負責在值有變化時,把對應的值賦值給對應dom節點的textContent
在這裏插入圖片描述
執行完這步後,此時節點的textContent就變成了Your name is test1
在這裏插入圖片描述

瀏覽器翻譯後

刷新瀏覽器恢復初始化數據,右擊翻譯後開始調試。
1)翻譯後,DOM結構有什麼變化?
可以看到谷歌翻譯後,dom節點自動添加了<font></font>標籤,如圖:
在這裏插入圖片描述
2)setTextContent是否還有執行?
經調試發現此方法仍有執行,並且text是正常的。
在這裏插入圖片描述
結論:問題出在傳進來的node,node是舊虛擬DOM對應的真實DOM,由於翻譯導致DOM結構發生了變化,在執行node.textContent = text前,這個node已經不存在了。

驗證

如果結論正確,那麼到node.textContent = text前,結果都還是符合預期的,我們給vue源碼增加一句代碼,把這個找不到了的DOM節點重新掛載到文檔中,如下箭頭所示:

在這裏插入圖片描述
運行結果:
輸入test1,雖然谷歌翻譯的那段沒變化,但document.body.appendChild(node)得到了想要的結果,控制檯訪問一下data中的name,也是有更新的。
在這裏插入圖片描述
再試試數據驅動,也還可行:
在這裏插入圖片描述
快速地敲一敲,也行得通:
在這裏插入圖片描述
從這個角度來說,谷歌瀏覽器翻譯後,Vue雙向數據綁定其實並沒有失效,只是翻譯導致DOM結構發生了變更,Vue找不到原來的節點去更新數據了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章