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!