vue報(bào)錯(cuò)Failed to execute 'appendChild' on 'Node'解決
一、問題描述
某天在開發(fā)需求時(shí)發(fā)現(xiàn),業(yè)務(wù)頁面上報(bào)告了一個(gè)Script error。

由于vconsole看不到詳細(xì)報(bào)錯(cuò)信息,于是在chrome上打開,具體報(bào)錯(cuò)信息如下:

Uncaught DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method. at Object.appendChild
看起來是vue2.6.12包里報(bào)了一個(gè)錯(cuò)誤,但從報(bào)錯(cuò)提供的信息看不出來那行代碼引發(fā)的報(bào)錯(cuò)。
二、解決過程
1、google:
解決問題的第一步往往是先看看“別人咋解決的”:把錯(cuò)誤信息ctrl+c ctrl+v到瀏覽器里google一下先。
stackoverflow里看到的第一個(gè)解決方案是通過添加client-only標(biāo)簽:
<template>
<div id="container">
<client-only>
<Components>
</client-only>
<div>
</template>
在項(xiàng)目里也照著這個(gè)方法在App.vue里添加client-only標(biāo)簽,重試后發(fā)現(xiàn)沒有效果,依然報(bào)錯(cuò)。
也有說法說是由于標(biāo)簽的關(guān)閉寫法導(dǎo)致的Hydration errors。

于是我搜索了下項(xiàng)目代碼,發(fā)現(xiàn)確實(shí)有幾處標(biāo)簽是使用類似 <span class="split" /> 寫法進(jìn)行關(guān)閉的。抱著嘗試的心理,我把這些寫法都改成了<span class="split"></span>。
然而重試后依然沒有解決這個(gè)報(bào)錯(cuò)。
2、斷點(diǎn)調(diào)試:
既然網(wǎng)上的方法沒有效果,那只能打斷點(diǎn)看看是否能找到報(bào)錯(cuò)的具體位置。
從錯(cuò)誤報(bào)告點(diǎn)擊進(jìn)詳情,可以看到是vue.min.js文件的appendChild拋出的錯(cuò)誤。

在這里打一個(gè)斷點(diǎn),并運(yùn)行:
第一次經(jīng)過此處:e是一個(gè)div,t是一個(gè)#comment的node節(jié)點(diǎn),此時(shí)還沒有拋出錯(cuò)誤。

第二次經(jīng)過此處:e是一個(gè)div,t是一個(gè)text元素,此時(shí)還沒有拋出錯(cuò)誤。

第三次經(jīng)過此處:e是#comment的node節(jié)點(diǎn),t是一個(gè)按鈕的div元素,此處拋出了對應(yīng)的錯(cuò)誤。

也就是在第三次運(yùn)行appendChild時(shí),由于e此時(shí)是一個(gè)node節(jié)點(diǎn),不支持appendChild方法,于是vue拋出了Uncaught DOMException: Failed to execute 'appendChild' on 'Node': This node type does not support this method.錯(cuò)誤。
在項(xiàng)目里搜索comment,發(fā)現(xiàn)并沒有找到相應(yīng)的代碼。于是從第三次appendChild的t參數(shù)入手。

可以看出來這是一個(gè)按鈕元素,并且按鈕文字內(nèi)容是“我知道了”。在項(xiàng)目里搜索“我知道了”,可以找到兩處符合條件的元素。根據(jù)此時(shí)的頁面位置可以排除captcha組件,所以鎖定了verifyResult組件里的“我知道了”按鈕。
這處按鈕的html代碼如下:
<q-button
v-if="resultInfo.showBtn"
type="primary"
@click="resultInfo.callback"
>
{{ resultInfo.btnText }}
</q-button>
先把這部分內(nèi)容直接注釋掉看看。 發(fā)現(xiàn)這個(gè)報(bào)錯(cuò)確實(shí)不見了??梢源_認(rèn),這個(gè)按鈕就是報(bào)錯(cuò)的源頭。
3、定位:
那這個(gè)按鈕到底有啥問題呢?看起來就是一個(gè)平平無奇的確認(rèn)按鈕呀。
從剛剛打斷點(diǎn)的時(shí)候可以看到,此時(shí)按鈕的text正常取到了"我知道了"文案,且報(bào)錯(cuò)信息是在進(jìn)行appendChild,也就是添加元素的動作時(shí)。而這個(gè)按鈕里用到了v-if,合理懷疑是這個(gè)v-if引起的。于是嘗試把v-if去掉或改成一個(gè)常量,發(fā)現(xiàn)頁面也不會報(bào)錯(cuò)。
所以可以確定,這里的報(bào)錯(cuò)是由于v-if的參數(shù)引起的。
這里v-if的參數(shù)是:resultInfo.showBtn
這里resultInfo是一個(gè)計(jì)算參數(shù):

showBtn是通過另一個(gè)計(jì)算參數(shù):isMobile來控制的。

看來問題就在isMobile上。
通過打印isMobile發(fā)現(xiàn),在node時(shí)由于沒有window,所以isMobile=false,而頁面渲染時(shí)isMobile=true。
所以這里isMobile有一個(gè)從false -> true的變化。


所以這里按鈕元素經(jīng)歷了從無到有的過程,在appendChild的時(shí)候node節(jié)點(diǎn)就拋出了錯(cuò)誤。
4、解決
這里解決方案的主要就是去掉這個(gè)從無到有的過程,或者把這個(gè)變化后移。
- 去掉這個(gè)從無到有的過程:把
v-if改成v-show。 - 把這個(gè)變化后移:isMobile不使用計(jì)算參數(shù),在默認(rèn)初始化為false,在created時(shí)再進(jìn)行賦值。
created() {
this.isMobile = browser.isMobile();
}
兩種方法都可以解決,我這里使用了第一種解決方案,報(bào)錯(cuò)不再出現(xiàn),且頁面按鈕可以正常顯示~
以上就是vue報(bào)錯(cuò)Failed to execute 'appendChild' on 'Node'解決的詳細(xì)內(nèi)容,更多關(guān)于vue 報(bào)錯(cuò)解決的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue+element-ui中form輸入框無法輸入問題的解決方法
很多初次接觸element-ui的同學(xué),在用到element form組件時(shí)可能會遇到input框無法輸入文字的問題,下面這篇文章主要給大家介紹了關(guān)于vue+element-ui中form輸入框無法輸入問題的解決方法,需要的朋友可以參考下2023-04-04
vue.js中父組件調(diào)用子組件的內(nèi)部方法示例
這篇文章主要給大家介紹了關(guān)于vue.js中父組件調(diào)用子組件內(nèi)部方法的相關(guān)資料,文中給出來了詳細(xì)的示例代碼供大家參考學(xué)習(xí),對大家的學(xué)習(xí)或者工作具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10
vue前端實(shí)現(xiàn)dhtmlxgantt甘特圖代碼示例(個(gè)人需求)
這篇文章主要介紹了如何使用dhtmlx-gantt和chinese-days插件在項(xiàng)目中實(shí)現(xiàn)節(jié)假日置灰顯示的功能,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-03-03
使用vue實(shí)現(xiàn)pdf預(yù)覽功能的方法
許多朋友想要材料上傳之后點(diǎn)擊預(yù)覽實(shí)現(xiàn)在瀏覽器上預(yù)覽的效果,所以本文將給大家介紹如何使用vue實(shí)現(xiàn)pdf預(yù)覽功能,文中有實(shí)現(xiàn)代碼,有需要的朋友可以參考閱讀下2023-08-08
vue2.0在沒有dev-server.js下的本地?cái)?shù)據(jù)配置方法
這篇文章主要介紹了vue2.0在沒有dev-server.js下的本地?cái)?shù)據(jù)配置方法的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-02-02

