Vue error makes no sense: Unhandled error during execution of scheduler flush. onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< null > >

Viewed 15050

I think this problem stems from a parent template having multiple children in Vue.js 3 with Vue Router 4. I never had this problem in prior version of both packages.

I have a simple App.vue file:

<template>
    <div id="app">
         <main id="content">
                    <div id="nav">
                        <!--<router-link to="/about">About</router-link>-->
                        <router-link to="/information">Information</router-link>
                        <router-link :to="{ path: '/create', name: 'PostCreate'}">Create</router-link>
                    </div>
                    <router-view></router-view>
         </main>
</template>

The router-link to="/information" link works fine. It just loads the view which has no other components inside it.

The other router-link :to="{ path: '/create', name: 'PostCreate'}" fails after repeatedly trying to load the component about 50 times and logs this in the console:

 [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 <PostCreate> 
  at <PostCreate>  
  at <PostCreate>  
  ... // repeats over and over again until
  at <PostCreate onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< null > > 
  at <RouterView> 
  at <App> 
  at <App>

vuerouter.js

const routes = [
    {
        path: '/',
        name: 'HomeView',
        component: HomeView
    },
    {
        path: '/information',
        name: 'Information',
        component: () => import(/* webpackChunkName: "Information" */ '../views/information/Information.vue')
    }
    ,
    {
        path: '/create',
        name: 'PostCreate',
        component: () => import(/* webpackChunkName: "Create" */ '../views/posts/PostCreate.vue')
    }
];

The only difference between Information.vue and PostCreate.vue is that the latter imports another vue component to make a form for the user to create a post.

Information.vue

<template>
<div>
<p>I am full of good info</p>
</div>
</template>
<script>
    export default {
        name: 'Information'
    }
</script>

PostCreate.vue

<template>
    <div class="content">

            <h1>I make a form</h1>
            <Post-Create></Post-Create>

    </div>
</template>

<script>
    import PostCreate from "../../components/PostCreate.vue";

    export default {
        name: "PostCreate",
        components: {
            "Post-Create": PostCreate
        }
    }
</script>

Why is this an issue in Vue.js 3 with Vue-Router 4 whereas it worked fine previously? How do I solve it?

1 Answers

This happens because the PostCreate view is trying to recursively load itself. Since you used the same name for the view and the child component, the parent name overwrites the child name in the registration, and the view tries to load itself instead of the child.

It's the equivalent of this, which would also lead to the view trying to load itself.

<template>
  <div class="content">
    <h1>I make a form</h1>
    <PostCreate></PostCreate>
  </div>
</template>

<script>
export default {
  name: "PostCreate",
};
</script>

You won't get a Failed to resolve component error, because it takes <PostCreate></PostCreate> to be itself. You get that same recursion error instead.

So you just need to rename the child component. It's a good practice to always use different filenames too, for different components, especially in larger projects, to keep files clear.

Related