[Vue 警告]:nextTick 中的错误:“NotFoundError:无法在 'Node' 上执行 'insertBefore'
Posted
技术标签:
【中文标题】[Vue 警告]:nextTick 中的错误:“NotFoundError:无法在 \'Node\' 上执行 \'insertBefore\'【英文标题】:[Vue warn]: Error in nextTick: "NotFoundError: Failed to execute 'insertBefore' on 'Node'[Vue 警告]:nextTick 中的错误:“NotFoundError:无法在 'Node' 上执行 'insertBefore' 【发布时间】:2019-01-10 04:46:56 【问题描述】:我偶尔会在我的 Vue Web 应用程序中收到以下错误消息,但当它确实发生时,它会完全停止我的应用程序。
错误信息 1:
[Vue 警告]:nextTick 中的错误:“NotFoundError:执行失败 'Node' 上的 'insertBefore':新节点所在的节点 插入的不是该节点的子节点。”
错误信息 2:
DOMException: 无法在 'Node' 上执行 'insertBefore': 节点 要插入的新节点之前不是 this 的子节点 节点。
错误消息 1 的堆栈跟踪:
错误消息 2 的堆栈跟踪:
根据堆栈跟踪,我已经确定我的仪表板组件中的 setListingFromCoords() 方法导致了问题。问题也不在于 vuex "getListingsFromCoords" 操作,因为 "data" 是 console.logged 正确的信息。此外, data.results 也被正确填充。 根据堆栈跟踪的问题是this.listings = data.results
。
下面是我的 setListingFromCoords() 方法,它位于仪表板组件中:
setListingFromCoords()
return new Promise((resolve, reject) =>
this.$store.dispatch(
"getListingsFromCoords"
).then((data) =>
console.log(data); // "data" is returned correctly here
this.listings = data.results; // CODE BREAKS HERE
this.previous = data.previous;
this.hasPrevious = data.hasPrevious;
this.next = data.next;
this.hasNext = data.hasNext;
resolve();
).catch((err) =>
reject(err);
);
);
,
在我的仪表板组件的模板部分中,我有以下卡片组件,它是基于上述 setListingFromCoords 方法返回的列表数量的 v-for'ed。这是唯一依赖 listings
的组件,这让我相信这部分会以某种方式导致 Vue 抛出错误。
<card
v-for="(listing, index) in listings"
v-bind:index="index"
v-bind:key="listing._id">
</card>
有人可以确认我的结论是否合理/正确。另外,我该如何修改我的代码来解决这个问题?为什么会抛出这个错误?
【问题讨论】:
【参考方案1】:我在vue-router
遇到了类似的问题,结果我将<router-view />
包装在vue-fragment
中。
编辑
这个问题是在vue-fragment v1.5.2 中引入的,请将包降级到 v1.5.1。
正如@jai-kumaresh 提到的,在 package.json "vue-fragment": "^1.5.1"
中删除 ^
,这样 npm 将只安装完全相同的版本。
编辑2021 年 10 月
如果您使用的是 Vue 3,则不再需要vue-fragment
包,现在您可以直接向根元素添加多个元素。
有关该主题的更多信息,请查看 Vue3 指南中的 fragments 部分。
【讨论】:
1.删除 package.json 中的^
"vue-fragment": "^1.5.1",
2。然后再次运行 npm i
。
只有vue-fragment
1.5.1 更新以上的包才会发生这种情况。
谢谢你,你在两个项目中救了我的命:D
有没有跟进为什么这个包更新引入了这个问题?【参考方案2】:
以下内容来自 VueJS 核心团队成员@LinusBorg:
错误消息本身是 Vue 尝试插入的 DOM 异常 一个元素在另一个元素之前,但该元素不再存在 在 DOM 中。
结合您提供的信息,我认为 Vue 尝试在 DOM 中的另一个元素之前插入一个元素 先前由 v-for 创建 - 换句话说,Vue 试图 用它认为的变化修补现有的元素列表 必须反映列表中的更改,并且失败,
我看不到任何直接导致此错误的东西,我唯一的怀疑 是不是你有重复的listing._id?
他的怀疑是正确的。我的仪表板组件中有一个重复的键,这导致了错误。
【讨论】:
不是最初的问题提问者的情况,但如果其他人遇到这个问题,因为它是一个流行的错误。如果你不是在声明一个 v-else 而是连续两个 v-if,它也可能发生!!!【参考方案3】:我在使用 Vue Slick 滑块时遇到了类似的问题:在我的情况下,解决方案是用 v-show
指令替换组件周围的 v-if
指令。一开始我还删除了生成幻灯片的循环中的:key
,但最后我能够再次使用这些键。
【讨论】:
【参考方案4】:我也遇到了同样的问题。
参与者:我自己的个人资料表单组件+youtube component。
<youtube
v-if="profileData.showYoutube && profileData.youtubeUrl"
:video-id="$youtube.getIdFromUrl(profileData.youtubeUrl)"
/>
问题:如果用户查看一些加载了 youtube 组件的个人资料,然后通过点击“创建个人资料”,用户会被vue-router
从site.com/some_profile_name
重定向到site.com/create_profile
。作为一个额外的步骤profileData
被清理(因为用户想要创建一个新的配置文件......)。
在这种情况下,两个组件都被重用了,但 youtube
出于某种原因,因为 profileData
清理是问题的根源:[Vue warn]: Error in nextTick: "NotFoundError: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node."
解决方案:我能够通过用<div>
包装youtube
组件来修复它(<template>
也会产生错误):
<div v-if="profileData.showYoutube && profileData.youtubeUrl">
<youtube :video-id="$youtube.getIdFromUrl(profileData.youtubeUrl)"/>
</div>
【讨论】:
【参考方案5】:我们在使用带有 v-if 的 <template>
元素时看到了这个错误。
如果我们转换为<div>
,它似乎可以修复它。
它最终会浪费一点 html,但它确实解决了问题。
【讨论】:
这也是我遇到的问题。在我将我的内部<template>
标签交换为 <div>
之后,它似乎也解决了这个问题 thx【参考方案6】:
-
从 vue-fragment 版本 1.52 降级到版本 1.51 并且不要在版本上添加 ^,现在坚持使用 1.51,因为错误在版本 1.52 上
2.如果你仍然有这个问题尝试删除片段标签周围
所以而不是:
<template>
<fragment><router-view></router-view></fragment>
</template>
简单地说:
<template>
<router-view></router-view>
</template>
或者如果你可以只用其他html标签包装这个路由器视图而不是
内部的组件仍然可以使用
【讨论】:
以上是关于[Vue 警告]:nextTick 中的错误:“NotFoundError:无法在 'Node' 上执行 'insertBefore'的主要内容,如果未能解决你的问题,请参考以下文章