执行调度程序刷新期间未处理的错误。这可能是 Vue 内部错误
Unhandled error during execution of scheduler flush. This is likely a Vue internals bug
我在 Vue.js 中创建幻灯片时遇到以下错误:
[Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next
at <Anonymous key=1 >
at <Anonymous pager="true" options= {initialSlide: 1, speed: 400} >
at <Anonymous fullscreen=true >
at <IonPage isInOutlet=true registerIonPage=fn<registerIonPage> >
at <Product Details ref=Ref< Proxy {…} > key="/products/1" isInOutlet=true ... >
at <IonRouterOutlet>
at <IonApp>
at <App>
Uncaught (in promise) DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
at insert (webpack-internal:///./node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js:222:16)
at mountElement (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:3958:9)
at processElement (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:3899:13)
at patch (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:3819:21)
at componentEffect (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:4312:21)
at reactiveEffect (webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:71:24)
at effect (webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:46:9)
at setupRenderEffect (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:4277:89)
at mountComponent (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:4235:9)
at processComponent (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:4195:17)
如果我添加硬编码的幻灯片,它不会显示任何错误。但是,如果我使用 v-for
循环动态添加幻灯片,则会显示上述错误。
我已按以下方式添加幻灯片:
这是模板:
<ion-slides pager="true" :options="slideOpts">
<ion-slide v-for="image in product.product_images" v-bind:key="image.id">
<h1>Slide 1</h1>
</ion-slide>
</ion-slides>
这是脚本:
export default {
name: "Product Details",
components: {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar,
IonSlides,
IonSlide,
},
data() {
return {
product: {},
};
},
setup() {
// Optional parameters to pass to the swiper instance. See http://idangero.us/swiper/api/ for valid options.
const slideOpts = {
initialSlide: 1,
speed: 400,
};
return { slideOpts };
},
mounted: function () {
fetch("http://localhost:4000/api/products/" + this.$route.params.id, {
method: "get",
})
.then((response) => {
return response.json();
})
.then((jsonData) => {
this.product = jsonData;
// console.log(jsonData.product_images);
});
},
};
我在代码中做错了什么?
可以说,这个错误消息可以改进。
该错误是由于尝试使用 v-for
迭代不可迭代对象(在您的情况下 undefined
)引起的。具体来说,在 mount()
returns 中进行的调用之前,product.product_images
是 undefined
,因为您将 product
初始化为空对象。
Vue 2 风格解决方案
- 将
product.product_image
实例化为可迭代的:
//...
data: () => ({
product: { product_images: [] }
})
或在模板中提供一个空数组作为回退:
<ion-slide v-for="image in product.product_images || []" v-bind:key="image.id">
<h1>Slide 1</h1>
</ion-slide>
或者在 v-for
的父级上放置一个 v-if
:
<ion-slides pager="true" :options="slideOpts" v-if="product.product_images">
...
</ion-slides>
Vue 3 风格解决方案
通过给它一个 async setup
函数,使整个 ProductDetails
组件暂停。在setup
函数中,调用获取产品。
概念验证:
//...
async setup() {
const product = await fetch("http://localhost:4000/api/products/" +
this.$route.params.id, {
method: "get",
}).then(r => r.json());
return { product }
}
现在将 <product-details>
放入 <Suspense>
的 <template #default>
,提供后备模板(将在 <Suspense>
解析其中找到的所有异步组件时呈现默认模板):
<Suspense>
<template #default>
<product-details></product-details>
</template>
<template #fallback>
Product is loading...
</template>
</Suspense>
使用 <Suspense>
的优点(和优雅)在于父级不需要知道尚未呈现标记的实际条件。它只是等待所有悬而未决的组件解决。
简而言之,使用 <Suspense>
您不再需要使用 v-if
s 将渲染逻辑硬编码到模板中并在包装器上明确指定条件。每个异步子组件都包含自己的条件,并且它向父组件宣布的只是:我完成了。全部完成后,它们就会被渲染。
还有 运行 当 hook 格式不正确时(created
、mounted
等)也会出现此错误。在我的例子中,created
是一个对象而不是一个函数。
差:
created: { /* some code */ }
好:
created() { /* some code */ }
// or...
created: function() { /* some code */ }
能否更改组件名称?
export default
name: "Product Details" ... <= here
这为我修复了这个错误。
错误:
describe('App', () => {
it('test 1', () => {
const wrapper = shallowMount(Component)
expect(wrapper.find('h2').text()).toEqual("my text")
})
it('test 2', () => {
const wrapper = shallowMount(Component)
expect(wrapper.find('h3').text()).toEqual("my othertext")
})
})
没有 :
describe('App', () => {
const wrapper = shallowMount(Component)
it('test 1', () => {
expect(wrapper.find('h2').text()).toEqual("my text")
})
it('test 2', () => {
expect(wrapper.find('h3').text()).toEqual("my othertext")
})
})
我在 Vue.js 中创建幻灯片时遇到以下错误:
[Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next
at <Anonymous key=1 >
at <Anonymous pager="true" options= {initialSlide: 1, speed: 400} >
at <Anonymous fullscreen=true >
at <IonPage isInOutlet=true registerIonPage=fn<registerIonPage> >
at <Product Details ref=Ref< Proxy {…} > key="/products/1" isInOutlet=true ... >
at <IonRouterOutlet>
at <IonApp>
at <App>
Uncaught (in promise) DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
at insert (webpack-internal:///./node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js:222:16)
at mountElement (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:3958:9)
at processElement (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:3899:13)
at patch (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:3819:21)
at componentEffect (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:4312:21)
at reactiveEffect (webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:71:24)
at effect (webpack-internal:///./node_modules/@vue/reactivity/dist/reactivity.esm-bundler.js:46:9)
at setupRenderEffect (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:4277:89)
at mountComponent (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:4235:9)
at processComponent (webpack-internal:///./node_modules/@vue/runtime-core/dist/runtime-core.esm-bundler.js:4195:17)
如果我添加硬编码的幻灯片,它不会显示任何错误。但是,如果我使用 v-for
循环动态添加幻灯片,则会显示上述错误。
我已按以下方式添加幻灯片:
这是模板:
<ion-slides pager="true" :options="slideOpts">
<ion-slide v-for="image in product.product_images" v-bind:key="image.id">
<h1>Slide 1</h1>
</ion-slide>
</ion-slides>
这是脚本:
export default {
name: "Product Details",
components: {
IonContent,
IonHeader,
IonPage,
IonTitle,
IonToolbar,
IonSlides,
IonSlide,
},
data() {
return {
product: {},
};
},
setup() {
// Optional parameters to pass to the swiper instance. See http://idangero.us/swiper/api/ for valid options.
const slideOpts = {
initialSlide: 1,
speed: 400,
};
return { slideOpts };
},
mounted: function () {
fetch("http://localhost:4000/api/products/" + this.$route.params.id, {
method: "get",
})
.then((response) => {
return response.json();
})
.then((jsonData) => {
this.product = jsonData;
// console.log(jsonData.product_images);
});
},
};
我在代码中做错了什么?
可以说,这个错误消息可以改进。
该错误是由于尝试使用 v-for
迭代不可迭代对象(在您的情况下 undefined
)引起的。具体来说,在 mount()
returns 中进行的调用之前,product.product_images
是 undefined
,因为您将 product
初始化为空对象。
Vue 2 风格解决方案
- 将
product.product_image
实例化为可迭代的:
//...
data: () => ({
product: { product_images: [] }
})
或在模板中提供一个空数组作为回退:
<ion-slide v-for="image in product.product_images || []" v-bind:key="image.id">
<h1>Slide 1</h1>
</ion-slide>
或者在 v-for
的父级上放置一个 v-if
:
<ion-slides pager="true" :options="slideOpts" v-if="product.product_images">
...
</ion-slides>
Vue 3 风格解决方案
通过给它一个 async setup
函数,使整个 ProductDetails
组件暂停。在setup
函数中,调用获取产品。
概念验证:
//...
async setup() {
const product = await fetch("http://localhost:4000/api/products/" +
this.$route.params.id, {
method: "get",
}).then(r => r.json());
return { product }
}
现在将 <product-details>
放入 <Suspense>
的 <template #default>
,提供后备模板(将在 <Suspense>
解析其中找到的所有异步组件时呈现默认模板):
<Suspense>
<template #default>
<product-details></product-details>
</template>
<template #fallback>
Product is loading...
</template>
</Suspense>
使用 <Suspense>
的优点(和优雅)在于父级不需要知道尚未呈现标记的实际条件。它只是等待所有悬而未决的组件解决。
简而言之,使用 <Suspense>
您不再需要使用 v-if
s 将渲染逻辑硬编码到模板中并在包装器上明确指定条件。每个异步子组件都包含自己的条件,并且它向父组件宣布的只是:我完成了。全部完成后,它们就会被渲染。
还有 运行 当 hook 格式不正确时(created
、mounted
等)也会出现此错误。在我的例子中,created
是一个对象而不是一个函数。
差:
created: { /* some code */ }
好:
created() { /* some code */ }
// or...
created: function() { /* some code */ }
能否更改组件名称?
export default
name: "Product Details" ... <= here
这为我修复了这个错误。
错误:
describe('App', () => {
it('test 1', () => {
const wrapper = shallowMount(Component)
expect(wrapper.find('h2').text()).toEqual("my text")
})
it('test 2', () => {
const wrapper = shallowMount(Component)
expect(wrapper.find('h3').text()).toEqual("my othertext")
})
})
没有 :
describe('App', () => {
const wrapper = shallowMount(Component)
it('test 1', () => {
expect(wrapper.find('h2').text()).toEqual("my text")
})
it('test 2', () => {
expect(wrapper.find('h3').text()).toEqual("my othertext")
})
})