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

fix(router-view): reuse saved instances in different records #446

Merged
merged 13 commits into from Sep 1, 2020

Conversation

posva
Copy link
Member

@posva posva commented Aug 26, 2020

Close #444

Still worth adding edge cases

  • Keep alive
  • Dynamic names

@github-actions
Copy link

github-actions bot commented Aug 26, 2020

size-limit report

Path Size
size-checks/webRouter.js 6.86 KB (+1.51% 🔺)
size-checks/webRouterAndVue.js 25.84 KB (+0.36% 🔺)

@posva
Copy link
Member Author

posva commented Aug 27, 2020

The problem with this fix is that it doesn't fix update and leave guards inside setup because setup doesn't get re-executed and I don't have a way to tell if and which component instances are reused. When a component instance is reused by Vue to render two different routes, one needs to use a key attribute to force the setup to get executed again. We could use the $route.path:

<router-view :key="$route.path" />

but that would also recreate routes with different params. A more appropriate solution would be using the record's path (doesn't include parsed params and it unique) and the name of the view (default when there is only one view). The problem is this information is not accessible right now outside of RouterView because one needs to know the depth:

<!-- path is here the record's path e.g. /users/:id -->
<router-view name="named" :key="'named_' + $route.matched[depth].path" />
<router-view :key="'default_' + $route.matched[depth].path" />

This information could be exposed through the v-slot when having the need to reuse the same component for different routes, something like key in addition to Component and route:

<router-view v-slot="{ Component, key }" >
  <component :key="key" :is="Component" class="view" />
</router-view>

Another solution would be able to enforce this automatically inside RouterView, removing the need to write any of the code above, but also removing the possibility to reuse component instances for different routes. IMO, this is fine because of the problem mentioned at the very beginning (setup guards) and because they will still keep being reused when params change which is the most important part.

Another problem with reusing the same component instance for two different routes is that guards added inside setup could be based on conditions like route.meta or others that would need to be evaluated again and that is only possible by not reusing the component instance.

BREAKING CHANGE: `onBeforeRouteLeave` and `onBeforeRouteUpdate` used to
have access to the component instance through `instance.proxy` but given
that:
1. It has been marked as `internal` (vuejs/core#1849)
2. When using `setup`, all variables are accessible on the scope (and
   should be accessed that way because the code minimizes better)
It has been removed to prevent wrong usage and lighten Vue Router
@posva posva force-pushed the fix/444/reused-instances branch 2 times, most recently from 20ffe71 to 6400619 Compare September 1, 2020 13:48
@posva
Copy link
Member Author

posva commented Sep 1, 2020

At the end I manage to find a solution that reuses view instances so I went with that instead

@posva posva changed the title fix(view): save reused instances in records fix(view): reuse saved instances in different records Sep 1, 2020
@posva posva changed the title fix(view): reuse saved instances in different records fix(router-view): reuse saved instances in different records Sep 1, 2020
@posva posva merged commit 6554171 into master Sep 1, 2020
@posva posva deleted the fix/444/reused-instances branch September 1, 2020 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

beforeRouteUpdate not work when different routes route to same Component
1 participant