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(nuxt): provide route component names to KeepAlive cache #24024

Merged
merged 5 commits into from Nov 14, 2023

Conversation

Clarkkkk
Copy link
Contributor

@Clarkkkk Clarkkkk commented Oct 30, 2023

πŸ”— Linked issue

#15214

❓ Type of change

  • πŸ“– Documentation (updates to the documentation, readme or JSdoc annotations)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • πŸ‘Œ Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

Hi, this PR is aimed to make the keepalive works as expected and fix #15214

Changes:

  • Change the nested order of the components in NuxtPage, letting KeepAlive read the correct component name
  • Change the relavant code to let them work the same way as before
  • Add tests for the keepalive features

There is one problem I am not sure about. In RouteProvider, it uses previousKey and previousRoute to "Prevent reactivity when the page will be rerendered in a different suspense fork" as the comment says, which I don't really understand. Since setup in RouteProvider will not rerun after all the changes, I use a watch to update previousKey and previousRoute. I don't know if it works the same way as before, and it seems there is no test case for this scenario.

πŸ“ Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@stackblitz
Copy link

stackblitz bot commented Oct 30, 2023

Review PR in StackBlitz Codeflow Run & review this pull request in StackBlitz Codeflow.

@Clarkkkk
Copy link
Contributor Author

A test about HMR failed, working on it.

@Clarkkkk
Copy link
Contributor Author

All tests have passed now.

package.json Outdated Show resolved Hide resolved
@Clarkkkk
Copy link
Contributor Author

Thanks for the quick review! All done.

@Maxbsy
Copy link

Maxbsy commented Nov 3, 2023

Tips:This branch is out-of-date with the base branch,You’re not authorized to merge this pull request.

@danielroe danielroe mentioned this pull request Nov 8, 2023
8 tasks
Copy link
Member

@danielroe danielroe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in further testing it seems that this change undoes the purpose of the route provider, which is to ensure a stably injected route in a suspense fork.

I've created a test (#24195) which should show the behaviour we want to have - once merged to main and updated in this pr, you can test it with:

pnpm nuxi dev test/fixtures/basic

and navigate to http://localhost:3000/route-provider/foo and then navigate to bar

@Clarkkkk
Copy link
Contributor Author

Clarkkkk commented Nov 9, 2023

Thanks! I will investigate it

@Clarkkkk
Copy link
Contributor Author

After some investigations, i found that the behavior of suspense and async component is heavily relying on the nested order of the components in page.ts. The change i've made breaks such behaviors and seems not likely to be fixed.

Another solution that comes to my mind is to set the component name of route-provider dynamically in render function. We could set the name same as its child component so that keep-alive can cache the right component. It may look confusing in vue dev tools since there are two components with the same name. But it seems acceptable as a temporary solution.

In the long run, to address this issue, keep-alive need to be enhanced in vue, and provide the ability to choose which vnode to cache by vnode key or some kind of mark.

Do you have any better idea? @danielroe

@danielroe
Copy link
Member

@Clarkkkk I think that would be a good solution. And I think we can only get rid of <RouteProvider> if this functionality is built into vue-router itself.

@Clarkkkk
Copy link
Contributor Author

I revert the previous changes and set the component name dynamically. <KeepAlive> should work as expected now.

The test result is different because onActivated is triggered before onDeactivated when using <Suspense> in <Keepalive>. And I believe it is the current behavior of Vue (example). So I update the test result to reflect this.

@danielroe danielroe changed the title fix(nuxt): keepalive does not work as expected fix(nuxt): add route component names to RouteProvider for keepalive cache Nov 14, 2023
@danielroe danielroe changed the title fix(nuxt): add route component names to RouteProvider for keepalive cache fix(nuxt): provide route component names to KeepAlive cache Nov 14, 2023
@danielroe danielroe merged commit 5493d60 into nuxt:main Nov 14, 2023
33 of 34 checks passed
@github-actions github-actions bot mentioned this pull request Nov 14, 2023
@freezyh
Copy link

freezyh commented Nov 23, 2023

πŸ”— Linked issue

#15214

❓ Type of change

  • πŸ“– Documentation (updates to the documentation, readme or JSdoc annotations)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • πŸ‘Œ Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

Hi, this PR is aimed to make the keepalive works as expected and fix #15214

Changes:

  • Change the nested order of the components in NuxtPage, letting KeepAlive read the correct component name
  • Change the relavant code to let them work the same way as before
  • Add tests for the keepalive features

There is one problem I am not sure about. In RouteProvider, it uses previousKey and previousRoute to "Prevent reactivity when the page will be rerendered in a different suspense fork" as the comment says, which I don't really understand. Since setup in RouteProvider will not rerun after all the changes, I use a watch to update previousKey and previousRoute. I don't know if it works the same way as before, and it seems there is no test case for this scenario.

πŸ“ Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

πŸ”— Linked issue

#15214

❓ Type of change

  • πŸ“– Documentation (updates to the documentation, readme or JSdoc annotations)
  • 🐞 Bug fix (a non-breaking change that fixes an issue)
  • πŸ‘Œ Enhancement (improving an existing functionality like performance)
  • ✨ New feature (a non-breaking change that adds functionality)
  • 🧹 Chore (updates to the build process or auxiliary tools and libraries)
  • ⚠️ Breaking change (fix or feature that would cause existing functionality to change)

πŸ“š Description

Hi, this PR is aimed to make the keepalive works as expected and fix #15214

Changes:

  • Change the nested order of the components in NuxtPage, letting KeepAlive read the correct component name
  • Change the relavant code to let them work the same way as before
  • Add tests for the keepalive features

There is one problem I am not sure about. In RouteProvider, it uses previousKey and previousRoute to "Prevent reactivity when the page will be rerendered in a different suspense fork" as the comment says, which I don't really understand. Since setup in RouteProvider will not rerun after all the changes, I use a watch to update previousKey and previousRoute. I don't know if it works the same way as before, and it seems there is no test case for this scenario.

πŸ“ Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

if I switch other layout, the keepalive will not work

@freezyh
Copy link

freezyh commented Nov 23, 2023

I revert the previous changes and set the component name dynamically. <KeepAlive> should work as expected now.

The test result is different because onActivated is triggered before onDeactivated when using <Suspense> in <Keepalive>. And I believe it is the current behavior of Vue (example). So I update the test result to reflect this.

switch other layout, the keepalive of before layout will not work

@transtone
Copy link

transtone commented Dec 27, 2023

the include method still have bug.
If use a array cacheList to control the keepalive page, add page name to cacheList will keep the page cache.
but when reduce the cacheList item, the page all refreshed!

<template>
      <NuxtPage :keepalive="{include:cacheList, max:20}" />
</template>
<script setup>
let cacheList = ref(['a','b','c'])
// the page a, b, c is cached.

const updateCacheList = ()=>{
   cacheList.value = ['a','b']
   router.push({path: '/c'})
  // when chanage route, the page 'a', 'b' refreshed!
}
</script>

this means it can't use a dynamic var to control the keepalive status.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

keepalive include/exclude props don't work with <NuxtPage>
5 participants