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

我在代码中做错了什么?

推荐答案

可以说,错误信息可以在这一条上得到改进.

该错误是由于try 使用v-for遍历不可iterable(在您的示例中为undefined)而导致的.具体来说,在mount()中进行的调用返回之前,product.product_imagesundefined,因为您将product初始化为空对象.

Vue 2 style solutions

  • product.product_image实例化为iterable:
//...
  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 style solution

Make the entire ProductDetails component suspensibe, by giving it an async setup function. In the setup function, make the call to get the product.
Proof of concept:

//...
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>

The beauty (and elegance) of using <Suspense> is that the parent doesn't need to know the actual condition(s) for which the markup is not yet to be rendered. It simply waits for all suspensible components to resolve.
In short, using <Suspense> you no longer need to hardcode the rendering logic into the template using v-ifs and specifying the condition in clear, on the wrapper. Each async child component contains its own condition and all it announces to the parent is: i'm done. When all are done, they're rendered.

Vue.js相关问答推荐

为什么在Vue.js中修改非react 性似乎是react 性的?

为什么我的数组在 onBeforeMount 函数中不为空,但在 onMounted 函数中为空

Vue3外部数组的响应性

作为props 传递的原始 ref 的 Vue 3 react 性

Vue,Composition API:如何从react 式转换中跳过深度嵌套的属性?

路径别名在 vue 脚本块中不起作用

两个div元素之间的vue2过渡

如何从mustache内的过滤器输出html

使用 Vue 和 JS 下载 CSV 文件

可以同时使用 Tailwind css 和 Bootstrap 4 吗?

Vue.js 从模板中分离样式

Keycloak:用户基于角色的客户端登录访问限制

NuxtServerInit 在 Vuex 模块模式下不起作用 - Nuxt.js

在Vue.js中从父组件执行子方法

Nuxt 应用程序在刷新动态路由时返回 404(Tomcat 服务器)

我在 Nuxt 2.14.0 中运行的是什么版本的 Vue?

Vuejs css 范围性能

如何在 Vue.js 中延迟 @keyup 处理程序

Vue $refs 对象的类型为 unknown未知

超过最大调用堆栈大小 Vuetify