Reputation: 20880
I use vue-router to navigate the user pages by their user id. And the router.js looks like as follows
export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/user/:id',
name: 'user',
component: () =>
import(/* webpackChunkName: "user" */ './views/User.vue'),
props: true
},
{
path: '/404',
name: '404',
component: () => import('./views/404.vue'),
},
]
})
If someone go to the URL of /user/some-invalid-id
, how do I redirect it to the 404 page?
In my app, all user data is loaded at the App.js' breforecreate()
, and internally the User view is accessed as follows for existing users
<router-link :to="{name: 'user', params:{id: u.pk}}" >
<a> {{u.first_name}} {{u.last_name}} </a>
</router-link>
I know it's possible to redirect programmatically with a push function call. But I don't know where this code should be used.
this.$router.push('/404')
In the User.vue
view page, I use a vuex getter called userByID
to retrieve data.
userByID: (state) => id => {
return state.users.find(u => (u.pk == id))
}
Should router.push('/404')
happen in userByID
or its caller? How do we deal with the template rendering with undefined
user object?
Upvotes: 2
Views: 6174
Reputation: 4714
I think you want to use 'Navigation Guards`, specifically a beforeEnter
hook in your /user/:id
route.
Something sort of like this (not tested; just directional):
routes: [
{
path: '/user/:id',
name: 'user',
component: () =>
import(/* webpackChunkName: "user" */ './views/User.vue'),
props: true,
beforeEnter: (to, from, next) => {
if (!userById($route.params.id)) {
next('/404');
}
else {
next();
}
}
}
},
{
path: '/404',
name: '404',
component: () => import('./views/404.vue'),
},
]
Note that you'll need to be able to determine if the user is valid without invoking the User.vue component.
You can also implement a beforeRouteEnter
hook on User.vue directly, though you'll not be able to call other User.vue methods there as the component won't yet be mounted.
More on navigation guards: https://router.vuejs.org/guide/advanced/navigation-guards.html#global-guards
Given your userById method is accessing the store, I found this post that might help you access the store in your beforeEnter
method: How to access async store data in vue-router for usage in beforeEnter hook?
Upvotes: 2