How to use a guard in vue to ignore the route rule? - vue.js

How to use a guard to move to next rule of route instead of redirect to specific route?
for example, I have some routes:
routes: [
{ path: '/', component: Main },
{ path: '/about', component: About },
{ path: '/:product', component: Product },
{ path: '*', component: NotFoundException }
]
and in Product component I have beforeRouteEnter function like that:
beforeRouteEnter(to, from, next) {
const question = checkIfExist(to.params.product);
if (question) { next(); return;}
next();
}
if the product not exist then it should be redirect to NotFoundException component. in the stackoverflow example I see only example with redirect to specific url (like login) which is not helpful.
When I given url: '/some' then vue check if:
is / ? no => next route.
is /about ? no => next route.
is /:product ? no => next route.
display NotFoundException component.

You can reference the next route by route name.
First, name your exception route
routes: [
{ path: '/', component: Main },
{ path: '/about', component: About },
{ path: '/:product', component: Product },
{ path: '*', name: 'notFound', component: NotFoundException }
]
Then, create a variable which stores your beforeEnter Logic
const productExists = (to, from, next) => {
const question = checkIfExist(to.params.product);
if (question) { next(); return;}
next({
name: "notFound"
});
}
Add the route guard to the routes that you want to guard
routes: [
{ path: '/', component: Main },
{ path: '/about', component: About },
{ path: '/:product', component: Product, beforeEnter: productExists },
{ path: '*', name: 'notFound', component: NotFoundException }
]

Related

I can't see .router-link-active or .router-link-exact-active on my route after I redirect route by using beforeEnter

I redirect component by using beforeEnter, and I don't see .router-link-active or .router-link-exact-active therefore css is not working. Please help me!
{
path: 'parent',
component: parent,
children: [
{
path: '',
name: 'ChildOne',
component: 'ChildOne'
},
{
path: 'two',
name: 'ChildTwo',
component: ChildTwo,
beforeEnter: (to, from, next) => {
if (isAuth) {
next({ name: 'ChildOne'})
} else {
next()
}
}
}
]
}
so.. it will redirect to ChildOne and ChildOne do not have .router-link-active or .router-link-exact-active.

Quasar \ VueJS 3 infinite route looping/

I got some routes in my routes.js file
path: '/main',
component: () => import('layouts/MainLayout.vue'),
beforeEnter: (to, from, next) => {
console.log(store.authState.auth.role)
if (Number(store.authState.auth.role) === 4) {
next({ path: '/main/admin' })
} else {
next()
}
},
children: [
{
path: '',
component: () => import('pages/Main.vue'),
meta: { requiresAuth: true }
},
{
path: 'user',
component: () => import('pages/User.vue'),
meta: { requiresAuth: true }
},
{
path: 'admin',
component: () => import('pages/Admin.vue'),
meta: { requiresAuth: true }
}
]
}
and i have some code in index.js router file:
Router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth) && !store.authState.auth.state) {
next({ path: '/' })
} else {
next()
}
})
The main idea was - if user not login - redirect to root, if user login and go to /main route, depends on his role router must redirect him to specific route.
But in fact - i got infinite loop for role === 4 (example) - what i do wrong? Thank you
Your beforeEnter navigation guard is being applied to the entire /main route, and /main/admin is nested within that route. That means that the guard is being called on /main/admin itself, so any admin user who requests that page (or is redirected to it) will be redirected from that page to itself.
Based on your description, you probably want to apply your navigation guard to just the exact /main route and not its entire tree. You could then go on to redirect to next({ path: '/main/user' }) instead of simply accepting the current path with next() at the end of the guard. If that's what you want, then you don't actually need a component there at all, since the route will never be rendered. Here's how that would look:
path: '/main',
component: () => import('layouts/MainLayout.vue'),
children: [
{
path: '',
component: () => import('pages/Main.vue'), // FIXME: not needed?
meta: { requiresAuth: true },
beforeEnter: (to, from, next) => {
if (Number(store.authState.auth.role) === 4) {
next({ path: '/main/admin' })
} else {
next({ path: '/main/user' })
}
},
},
{
path: 'user',
component: () => import('pages/User.vue'),
meta: { requiresAuth: true }
},
{
path: 'admin',
component: () => import('pages/Admin.vue'),
meta: { requiresAuth: true }
}
]
}

Is there a way to redirect a route inside group route?

Let's say I had this routes config:
pages
- index.vue
- admin
- login.vue
- register.vue
Is there a way to make /admin/login act as the index of admin routes? I want to simply redirect whoever hits /admin to /admin/login.
You could use middleware in /admin/index.vue, which has a redirect method in its context argument:
<script>
export default {
middleware({ redirect }) {
redirect(301, '/admin/login')
}
}
</script>
The vue-router supports redirect in the route definitions:
https://router.vuejs.org/guide/essentials/redirect-and-alias.html#redirect
const routes = [
/* ... */
{ path: '/admin', redirect: '/admin/login' },
{ path: '/admin/login', name: 'Login', component: LoginComponent },
{ path: '/admin/register', name: 'Register', component: RegisterComponent },
]
You can also define nested routes like so:
const routes = [
/* ... */
{
path: '/admin',
redirect: '/admin/login',
children: [
{
path: 'login',
name: 'Login',
component: LoginComponent
},
{
path: 'register',
name: 'Register',
component: RegisterComponent
}
]
}
]

VueJS pass parameters through the router next()

I want to pass the last route into my router when I'm in /login to redirect the user when is logged to desired route.
So the user go to /payment I redirect to /login and when the authentication is ok I want to redirect the user to payement
Here is my router.js :
import ...
Vue.use(Router)
let router = new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/login',
name: 'login',
component: Login
},
{
path: '/about',
name: 'about',
component: About
},
{
path: '/payment',
name: 'payment',
component: Payment,
meta: {
requiresAuth: true
}
},
{
path: '/my-account',
name: 'my-account',
component: MyAccount,
meta: {
requiresAuth: true
}
}
]
})
router.beforeEach((to, from, next) => {
console.log('Before Each Routes')
if(to.matched.some(record => record.meta.requiresAuth)) {
if (store.getters.isLoggedIn) {
console.log('Logged in')
next()
return
}
console.log(to.fullPath)
next({
path: '/login',
params: { nextUrl: to.fullPath }
})
return
} else {
console.log(to.fullPath)
next()
}
})
export default router
So I set some console.log and I got this :
if I go directly to /login, Output :
Before Each Routes
/login
Then if I go to /payment, Output :
Before Each Routes
/payment
Before Each Routes
/login
So now when I go in my login component and I use this.$route.params.nextUrl it's undefined. The next() parameter doesn't exist and I don't know why.
What I'm doing wrong ?
It looks like you're confusing two different mechanisms: params and query. Params have to be integral to the url, like /user/:id while query params are appended automatically.
You want this:
next({
path: '/login',
query: {
nextUrl: to.fullPath,
}
})
Related reading: https://router.vuejs.org/api/#route-object-properties
Tristan's approach above is the best when passing a url as a parameter. However, in normal cases we're passing something like an id so you can use this:
next({ name: 'account', params: { id: 3 } });
Add the replace option to prevent the navigation from appearing in the history:
next({ name: 'account', params: { id: 3 }, replace: true });
I'm using vue-router 3.1.6.

How to redirect user to a 404 page if a dynamic ID does exist in VueJS app?

how do I redirect a user to a 404 Not Found page if an ID does not exist?
I have a dynamic route like so:
const routes = [
{
path: '/',
component: Home
},
{
path: '/content',
component: DataTable
},
{
path: '/content/:NAS_ID', <----what if there's an NAS_ID that does not exist?
name: 'datadetail',
component: DataDetail
},
{
path: '/404',
component: NotFound
},
{
path: '*',
redirect: '/404'
}
];
How would I write a navigation guard for the invalid NAS_ID? Thank you.