framework
framework copied to clipboard
useRoute() in 'vue-router' is working but not in nuxt.
Environment
- Operating System:
Darwin - Node Version:
v18.7.0 - Nuxt Version:
3.0.0-rc.8 - Package Manager:
[email protected] - Builder:
vite - User Config:
modules,css,colorMode,vite,app - Runtime Modules:
[email protected],@pinia/[email protected],@nuxtjs/[email protected],@nuxt/[email protected] - Build Modules:
-
Reproduction
https://stackblitz.com/edit/github-izskfd?file=components/Book.vue
Describe the bug
useRoute(), nuxt default provided function, has previous route information, and not updated on moving page.
But using import { useRoute } from vue-router, resolve all problems.
Is there any point I missed?
Additional context
rc.6 doesn't have problems but rc.8 has.
It just occurred as soon as updating from rc.6 to rc.8
Logs
No response
/cc @danielroe
I got the same error in https://github.com/nuxt/framework/issues/6623 while using useRoute().
It seems it works again after restarting the server a couple time. I can not explain it for now. Restarting the server after the first cold start was also a workaround for #6623 if it can help.
The key thing is that you should not destructure params from the returned route object that Nuxt (or vue-router) provides, as it is a reactive object and destructuring anything from it causes it to lose reactivity.
- const { params } = useRoute()
+ const route = useRoute()
Once fixed, note that you were effective re-implementing a route that was always one step behind the actual route in app.vue. Here is a working example, with those two issues resolved: https://stackblitz.com/edit/github-izskfd-zzrrtu
I want to show Book Componenet with background (previous page), so I edited :route property on <NuxtPage>, still doesn't works route.params.id on Book.vue.
But I add import { useRoute } from 'vue-router' on Book.vue, it does work.
Please let me know where my mistake is...
app.vue:
...
- const route = useRoute();
const routeWithPopup = computed(() =>
+ historyState.value.background ? resolve(historyState.value.background) : undefined
);
...
...
+ <NuxtPage :route="routeWithPopup" />
...
components/Book.vue:
// When I add
// import { useRoute } from 'vue-router'
// It does work
const route = useRoute();
<!-- doesn't work with no import -->
<div>Book {{ route.params.id }}</div>
I have the exact same issue. Could also throw in the fact that if I have useFetch depend on route.params it doesn't update the param I use, regardless of if I use the Options API approach or Composition API using the vue-router workaround.
Here's my code examples:
Composition API
<script setup>
import { useRoute, useRouter } from 'vue-router';
const route = useRoute();
const { pending, data: pages, refresh } = await useLazyFetch(`/api/sites/${route.params.siteKey}/pages`);
watch(
() => route.params.siteKey, async siteKey => {
refresh();
}
);
</script>
Options API
<script type="ts">
import { defineComponent } from 'vue';
export default defineComponent({
async setup() {
const route = useRoute();
const { data, refresh: refreshPages } = await useFetch(`/api/sites/${route.params.siteKey}/pages`);
return {
pages: data.value,
refreshPages
}
},
watch: {
'$route.params.siteKey': function(oldValue, newValue) {
this.refreshPages();
}
}
});
</script>
In both cases, the watch sees the new value and it is in fact changed. However, the refetch(), or rather useFetch does not pick up the new param and instead uses the previous one, always. So after a second route change, it uses the one from the previous route change.
@danielroe should I open a new issue regarding the useFetch portion of the issue? Or could it be considered the same issue?
The issue here is that you should not import useRoute from vue-router but from #imports. We have a custom implementation of useRoute that handles some suspense related issues (https://github.com/nuxt/framework/pull/6275).
The useFetch issue you describe is already covered by https://github.com/nuxt/framework/issues/5993.
@danielroe Regarding the vue-router import, that is only to make it possible to listen to the route params changing using the Composition API approach as mentioned above. If I don't it doesn't react to any changes, regardless of me listening to the specific param siteKey, all params or the whole route itself.
Thank you for referring me to the other issue regarding useFetch! 🙏
|@danielroe hi, in my application i am changing page with NuxtLink and i am using useRoute in footer. when first load the page useRoute data works very well but after i change page fullpath doesnt change. How can i fix this can anyone help me please?
<script setup>
const route = useRoute()
const isPricing = computed(() => {
return route.fullPath === "/blablabla"
})
</script>
"nuxt": "3.0.0-rc.11",
@Ischafak my workaround (it's not very pretty) is to use state management that will refresh a variable 🤔.
In app.vue const isLink = linkStore() // I am using pinia let thisLink: string isLink.$subscribe(() => { thisLink = location.href // when the state change thisLink is updated })
Hi there !
Tiny ping because I'm also experiencing this issue.
Nuxt version 3.0.0-rc.11
Code example:
// experiences/index.js
<template>
<div>
<h1>Experiences</h1>
<ul>
<li>
<NuxtLink to="experiences/experience1">
<div>
<img src="/images/exp1.png" />
</div>
</NuxtLink>
</li>
<li>
<NuxtLink to="experiences/experience2">
<img src="/images/exp2.png" />
</NuxtLink>
</li>
</ul>
</div>
</template>
// experiences/[experience].js
<script setup>
import experiences from '@/data/experiences'
import { useRoute } from 'vue-router' // With this line it's working as expected
const route = useRoute()
const current = route.params.experience // This param is loaded once but never updated while the route changes
const experience = experiences[current] // So this variable always stays the same
</script>
For me too, the only way of making it work is to import manually import { useRoute } from 'vue-router'.
When counting on the auto import it simply doesn't work.
PS: Note that the problem doesn't come, at least in my case, from destructuring.
Thanks!