执行调度程序刷新期间未处理的错误。这可能是一个 Vue 内部错误

新手上路,请多包涵

在 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>

未捕获(承诺中)DOMException:无法在“节点”上执行“insertBefore”:要插入新节点的节点不是该节点的子节点。

 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);
      });
  },
};

我在代码中做错了什么?

原文由 Hello World 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 7.1k
2 个回答

可以说,这个错误消息可以得到改进。

该错误是由于尝试使用 v-for 迭代不可迭代(在您的情况下 undefined )引起的。 Specifically, before the call made in mount() returns, product.product_images is undefined , because you initiate product as empty object.

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-if 放在 v-for 的父级上:

 <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 }
}

Now place <product-details> into a <Suspense> ’s <template #default> , providing a fallback template (which will be rendered while <Suspense> all the async components在其默认模板中找到):

 <Suspense>
  <template #default>
    <product-details></product-details>
  </template>
  <template #fallback>
    Product is loading...
  </template>
</Suspense>

使用 <Suspense> 的美妙(和优雅)在于父级不需要知道尚未呈现标记的实际条件。它只是等待所有可挂起的组件解决。

简而言之,使用 <Suspense> 您不再需要使用 v-if 将渲染逻辑硬编码到模板中,并在包装器上明确指定条件。每个异步子组件都包含自己的条件,它向父组件宣布的只是:我完成了。全部完成后,它们被渲染。

原文由 tao 发布,翻译遵循 CC BY-SA 4.0 许可协议

这为我解决了这个错误。

有错误:

 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")
  })

})

原文由 karian 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题