vue-route-key
is a simple plugin for restart component when change route params and query.
- Restart component when change route params and query
- Force restart current component
First, Let's assume that you have a /profile/:id
and component call an api from created()
.
If you navigate from /profile/1
to /profile/2
, vue-router
does not call created()
.
Because it reuses a current component instead of restart and calls beforeRouteUpdate
.
I found some solutions:
- Use a watch: Is this the best way?
<router-view :key="$route.fullPath"/>
: Very simple and effective. But if you have nested routing, all components are restart. I want to restart a nested component only.
Second, If there is a link to the forum on the nav, people expect that page showing new contents when they click the link.
But nothing happens when they click the link. Because vue-router
blocks navigate to same location.
That is why I made this plugin.
This plugin consists of three parts.
- Override
vue-router
: Override thepush
andrelace
ofvue-router
to ignore duplicated error when using force update. - Router hook: This is the core part. It collects params and query information from components matched with current routing, generate a unique key value that can be used in
<router-view>
. - Mixin: This mixin inject the unique key value to component with the name
$routeKey
. It also serves force update feature.
The $routeKey
used as :key
attribute's value in <route-view>
. The component restart by changes of $routeKey
.
<router-view :key="$routeKey[0]" />
npm install --save vue-route-key
main.js
import Vue from 'vue';
import VueRouter from 'vue-router';
import VueRouteKey from 'vue-route-key';
const router = new VueRouter(/* ... */);
Vue.use(VueRouteKey, {
router, // Install plugin after create a router.
canIncrKey(depth = 0) { // (optional) determine force update
return true;
}
});
App.vue
<router-view :key="$routerKey[0]" />
<!--
append the :key="$routerKey[0]" in <router-view>.
Adjust the index according to the nested level.
-->
Component.vue
<script>
export default {
// ...
routeKey: [ // Type params and query you want to restart component if they changed.
'params.paramName',
'params.otherParam',
'query.queryName',
'query.otherQuery'
]
// ...
}
</script>
You can force update by params._forceUpdateIndex
sets depth of nested route-view.
this.$router.push({
name: 'page',
params: {
_forceUpdate: true, // Deprecated
_forceUpdateDepth: 0,
}
});
<router-link :to="{name: 'page', params: {_forceUpdateDepth: 0}}">link</router-link>
NOTE
If canIncrKey()
returns false, force update will be canceled.