Reputation: 44969
When using Vue Router with routes like /foo/:val
you have to add a watcher to react for parameter changes. That results in somewhat annoying duplicate code in all views that have parameters in the URL.
This could look like the following example:
export default {
// [...]
created() {
doSomething.call(this);
},
watch: {
'$route' () {
doSomething.call(this);
}
},
}
function doSomething() {
// e.g. request API, assign view properties, ...
}
Is there any other way to overcome that? Can the handlers for created
and $route
changes be combined? Can the reuse of the component be disabled so that the watcher would not be necessary at all? I am using Vue 2, but this might be interesting for Vue 1, too.
Upvotes: 33
Views: 17265
Reputation: 682
vue3 and script setup:
watch(route, () => { fetch()})
in import:
import { watch } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute()
Upvotes: 3
Reputation: 720
I used this variant without :key
prop on router-view
component.
routes.js:
{
path: 'url/:levels(.*)',
name: ROUTES.ANY_LEVEL,
props: true,
component: (): PromiseVue => import('./View.vue'),
},
view.vue
<template>
<MyComponent :config="config" />
</template>
---*****----
<script>
data: () => ({ config: {} }),
methods: {
onConfigurationChanged(route) {
const { params } = route
if (params && params.levels) {
this.config = // some logic
} else {
this.config = null
}
},
},
beforeRouteUpdate(to, from, next) {
this.onConfigurationChanged(to)
next()
},
}
</script>
Inside the component, I use the config as a property. In my case, reactivity is preserved and the component is updated automatically from parameter changes inside the same URL. Works on Vue 2
Upvotes: 0
Reputation: 44969
One possible answer that I just found thanks to a GitHub issue is the following.
It is possible to use the key
attribute that is also used for v-for
to let Vue track changes in the view. For that to work, you have to add the attribute to the router-view
element:
<router-view :key="$route.fullPath"></router-view>
After you add this to the view, you do not need to watch the $route
anymore. Instead, Vue.js will create a completely new instance of the component and also call the created
callback.
However, this is an all-or-nothing solution. It seems to work well on the small application that I am currently developing. But it might have effects on performance in another application. If you really want to disable the reuse of the view for some routes only, you can have a look at setting the key
's value based on the route. But I don't really like that approach.
Upvotes: 56