Subscribe on changes!

Unexpected Rendering behavior when using suspense and router-view

avatar
Sep 22nd 2020

Version

3.0.0

Reproduction link

Please test this locally too, Codesandbox seems to not put out various Console Errors and loads some Components compared to an Local Environment. https://codesandbox.io/s/vite-vue3-suspense-router-example-cwf00

Steps to reproduce

Steps to reproduce the Bugs:

  1. The Home Route wont automatically load (on local, works in codesandbox unfortunately) 1.1 On Local, the Home Route and Studio Route are not rendered <!---->. Just by clicking between the Routes multiple Times, the DOM eventually gets rendered 1.2 Clickbehavior like the following: Reload (no Home) -> Home -> Studio -> Home (now its rendered) 1.3 It is also possible to infinitely add <!----> to the DOM with that method
  2. If App.vue doesnt have a <div></div> within the default suspense template it will show the following console error: <Suspense> slots expect a single root node.
  3. But if the default suspense template has a <div></div>, vue router will add empty two <!----> into the dom, these do not exist if Point 2 is active
  4. The First Children Routecomponent (Studio1) is not loaded either on route change but on page reload 4.1 Refreash the Page and click from home to studio and you wont see "studio1" headline
  5. On local, studio 2 and studio 3 components have trouble loading with route change (but work on reload) if the children router-view is not located within a "suspense" same as the app.vue router-view

All these Issues are just occuring since the latest Suspense Change (as far as tested): https://github.com/vuejs/vue-next/pull/2099

What is expected?

Expected would be that a Route without any params would load on its specific Url, same goes for the Children Routes. Also there shouldnt be empty dom comments <!----> rendered just by adding a empty div to the suspense default template.

What is actually happening?

Routes without Params are not showing their specific async Component on local enviroment. Additional empty dom comments <!----> are getting rendered when using empty div tags in suspense default template together with a component slot from router-view


Tested on and with: "@vue/compiler-sfc": "^3.0.0", "vite": "^1.0.0-rc.4" "vue": "^3.0.0", "vue-router": "^4.0.0-beta.11"

Windows 10 64Bit, Terminal: Integrated VSCode Terminal

Additional

Atm there is no Documentation about how to use suspense and router-view properly together. There are old Bits out via Youtube Videos but this could lead to some confusion. There should be an official Doc where its explained atleast

avatar
Sep 23rd 2020

You need your studio_route component to have one single element at the root and to remove the div that wraps component in App.vue (https://github.com/vuejs/vue-next/issues/2143#issuecomment-694640896). Note Suspense is still experimental, its API and the way it's used to build apps is meant to adapt before we can dive into documenting it with components like router-view

avatar
Sep 23rd 2020

Thanks for the Answer! Completely over saw the last sentence in Evans Comment! But in general isnt this a little counterproductive? Vue 3 allows Fragments but with Async Setup and Suspense you are forced onto a single Root Element..

Also the other Bug doenst seem to get resolved from this Solution!

So ive added a one single element now to all templates and i am still getting the error: <Suspense> slots expect a single root node. at <RouterView> Which clearly shouldnt be there. The Children Index Route (studio.vue) doesnt automatically show its h1 tag either (only on reload, but not on route change)

Is it essential that each router-view needs a suspense? because ive seen on the vuemastery that normally one suspense should handle all async children components. Otherwise i dont know where the Error should come from.

Apparently also this Bug is now shown: Avoid app logic that relies on enumerating keys on a component instance. The keys will be empty in production mode to avoid performance overhead. All studio components should be fine so this kinda weird..

Codesandbox is now updated and shows both Bugs.

avatar
Sep 23rd 2020

Don't use defineAsyncComponent with the route views and it should remove the last error you are seeing.

Regarding using async setup in nested component it seems it changed (https://github.com/vuejs/vue-next/pull/2099) but I don't think it should break like it does, so I opened https://github.com/vuejs/vue-next/issues/2215

avatar
Sep 23rd 2020

Okay, so i removed defineAsyncComponent the last error message disappears but the first error with the single root node still persists even tho all components have only one root node.

Before #2099 the router-view behavior was fine with suspense, but thanks for opening #2215. Is this case also related to the children routes issue? So that they are not displayed on route change but on reload. I messaged you via Discord too, because i still feel like there is a bigger Bug going on that i cant really explain properly via Text!

avatar
Oct 2nd 2020

I've been tracking down this issue and I can confirm that sticking to vue@3.0.0-rc.5 version under yarn.lock fixes my issues with Suspense and router-views. You need to install dependencies with yarn --frozen-lock-file.

vue@^3.0.0-0:
  version "3.0.0-rc.5"
  resolved "https://registry.yarnpkg.com/vue/-/vue-3.0.0-rc.5.tgz#973175d45a892b3bd23ef5de7faa4add9c66275f"
  integrity sha512-8t8Y4sHMBGD5iLZ7JfBGmKBJlzesPoL+/nW9EV8s+4LwnKC4rGlRp+Lj2rcign4iQaj0GFaL7DrQ8IoOfVX6+w==
  dependencies:
    "@vue/compiler-dom" "3.0.0-rc.5"
    "@vue/runtime-dom" "3.0.0-rc.5"
    "@vue/shared" "3.0.0-rc.5"

I had a few stable projects working on beta version and they suddenly stopped working... Truth is we were warned about a changing API for Suspense from the beginning.

This PR shows the changes to get a working Vue3 app back to life: https://github.com/yeikiu/base-vue3-ts/pull/1/files#diff-8ee2343978836a779dc9f8d6b794c3b2L8832 maybe using the yarn.lock from develop branch there can help you temporarily...