Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for multiple route-views inside a transition/keep-alive #1118

Open
pearofducks opened this issue Sep 16, 2021 · 9 comments
Open

Support for multiple route-views inside a transition/keep-alive #1118

pearofducks opened this issue Sep 16, 2021 · 9 comments
Labels
discussion This problem still needs more feedback enhancement New feature or request needs RFC This feature needs to go through the RFC process first

Comments

@pearofducks
Copy link

What problem does this feature solve?

The following is not possible if the my-modal component has transitions.

<my-modal>
  <template #default>
    <router-view>
  </template>
  <template #footer>
    <router-view name="footer">
  </template>
</my-modal>

If there's no footer slot, we can of course use the pattern suggested in the Vue Router docs and use router-view's slot props:

<router-view #default="{ Component }">
  <my-modal>
    <template #default>
      <component :is="Component" />
    </template>
  </my-modal>
</router-view>

But then there's no (apparent) way to solve this usecase for the footer slot.

What does the proposed API look like?

Whatever is most practical.

Provide all named views on the main router-view:

<router-view #default="{ Component, Components }">
  <component :is="Component" />
  <component :is="Components.Footer" />
</router-view>

Or enable nested router-views to work with named routes? (This is the solution the Vue Discord chat thought was working today for this problem)

@posva
Copy link
Member

posva commented Sep 16, 2021

Do you have a boiled down snippet of what you are trying to achieve? It would help understanding

@pearofducks
Copy link
Author

Sure!

Effectively what's in the first snippet in my original post.

<my-modal>
  <template #default>
    <router-view>
  </template>
  <template #footer>
    <router-view name="footer">
  </template>
</my-modal>

However, since my-modal uses transitions [0], we instead have to do the following. The default content works fine, but then there's no way to get content from the route-view footer to the footer slot in MyModal.

<router-view #default="{ Component }">
  <my-modal>
    <template #default>
      <component :is="Component" />
    </template>
    <template #footer>
       <!-- how do we get the router-view below to work here? -->
       <router-view name="footer">
    </template
  </my-modal>
</router-view>

[0] - MyModal looks something like

<transition>
  <div>
      <slot />
  </div>
  <div>
      <slot name="footer" />
  </div>
</transition>

@posva
Copy link
Member

posva commented Sep 16, 2021

Ah I see now! Yeah that Components variable might be the easiest way

@posva posva added the enhancement New feature or request label Sep 16, 2021
@posva
Copy link
Member

posva commented Sep 29, 2021

After taking a look, this is currently not possible because one RouterView only renders itself and to be able to provide a Components property on the slot, we would have to render all views. So this would require activation through a prop but that simply doesn't sound right.

If your modal looks like

<transition>
  <div>
      <slot />
  </div>
  <div>
      <slot name="footer" />
  </div>
</transition>

Then it doesn't matter how you pass the views as they aren't wrapped by the transition anyway.

Or enable nested router-views to work with named routes? (This is the solution the Vue Discord chat thought was working today for this problem)

That would break the existing usage of nested named views.

Let's give this more thinking. In any case, it definitely requires going through an RFC.

@posva posva added the discussion This problem still needs more feedback label Sep 29, 2021
@baybal
Copy link

baybal commented Nov 27, 2021

I'm using fragment pages a lot. Now you can mount Vue on body element. There is no need for containers.

@pearofducks
Copy link
Author

@baybal - do you have an example of what you're referring to? I'm not sure how any of that relates to this issue.

@baybal
Copy link

baybal commented Nov 27, 2021

It just hit me it is not related

@posva posva added the needs RFC This feature needs to go through the RFC process first label Dec 1, 2021
@brendomaciel
Copy link

I believe I'm trying to achieve something similar for layouts. My ideia was to use named views to pass both view and layout in the route and then render it on the same place, like:

// routes.js
{
    path: 'sign-in',
    components: {
        default: SignInView,
        layout: AuthLayout,
    },
}

Then, in the root component:

<template>
    <RouterView v-slot="{ Component }" name="layout">
        <component :is="Component">
            <RouterView />
        </component>
    </RouterView>
</template>

But unfortunately the inner <RouterView /> don't render, only the outer one.

Live example.

@mkassm
Copy link

mkassm commented Aug 2, 2024

I have the same issue here as @brendomaciel mentioned

As @posva mentioned here in this comment #431 (comment) that nested named views using a slot is not supported yet and must be at the same level,
so is there any workaround that can be considered ?

Update
I think one workaround is to pass the layout component into route meta as mentioned here #539

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion This problem still needs more feedback enhancement New feature or request needs RFC This feature needs to go through the RFC process first
Projects
None yet
Development

No branches or pull requests

5 participants