-
-
Notifications
You must be signed in to change notification settings - Fork 5.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support array syntax in beforeEnter
#2688
Comments
For those interested in this feature request, is there any use case that requires array syntax for the in-component guards? I can see how having an array for |
At this moment, I can't think of a use-case that would require an Array based syntax for guards at component level, but are we sure that there wouldn't be? and would there be additional cost to add that syntax to component level? |
I used vue-router-multiguard when i needed to pass multiple guards to some pages on the previous project i worked on. |
beforeEnter
arrays for in-component guards seems unnecessary as a component guard is specific to a component, they are not reused. right, something like isAuthenticatedGuard will never be reused anywhere, its specific guard for specific component for specific route only... or not? What if we have more guards like localization? Captchas and other security which will be unnecessary to call if first failed? See Symfony Voters, they have somthing similar for PHP.
|
Not sure if this has been resolved within import {
createRouter,
createWebHistory,
NavigationGuard,
NavigationGuardNext,
RouteLocationRaw,
Router
} from "vue-router"
import {
doesNotHaveTeams,
hasTeams,
isAuthenticated,
isNotAuthenticated
} from "./guards"
/** Define provider signature **/
export type MultiGuard = (guards: NavigationGuard[]) => NavigationGuard
/**
* Provide routes with the ability to execute multiple guards.
* This is implemented due to a gap in Vue Router functionality which limits callbacks to a single guard.
*
* @see https://github.com/vuejs/vue-router/issues/2688
* @param {NavigationGuard[]} guards
* @return {NavigationGuard}
*/
export const multiGuard: MultiGuard =
(guards: NavigationGuard[]): NavigationGuard =>
async (to, from, next) => {
// Let sharedNext callback break execution if a guard is triggered.
let resolved: boolean = false
// Create a "shared" next callback which breaks the iteration loop if "next()" is called within guard.
// TODO: Implement "boolean" and "callback" cases...
const sharedNext = (location?: RouteLocationRaw): void => {
if (location) {
resolved = true
next(location)
}
}
// Iterate through provided guards array until complete or redirected.
for (const guard of guards) {
await guard(to, from, sharedNext as NavigationGuardNext)
// Check if the sharedNext callback triggered a break.
if (resolved) {
break
}
}
// If none of the guards triggered a redirect, allow the original intent.
if (!resolved) {
next()
}
}
/**
* Example multiguard implementation.
*
* @type {Router}
*/
export const router: Router = createRouter({
history: createWebHistory(),
routes: [
{
path: "/teams",
name: TEAMS_ROUTE,
beforeEnter: multiGuard([isAuthenticated, hasTeams]),
component: () => import("/@src/pages/teams.vue")
},
{
path: "/onboarding",
name: ONBOARDING_ROUTE,
beforeEnter: multiGuard([isAuthenticated, doesNotHaveTeams]),
component: () => import("/@src/pages/onboarding.vue")
},
{
path: "/sign-in",
name: SIGN_IN_ROUTE,
beforeEnter: multiGuard([isNotAuthenticated]),
component: () => import("/@src/pages/auth/sign-in.vue")
}
]
})
Example route guard. /**
* Example route guard.
*
* @param {RouteLocationNormalized} _to
* @param {RouteLocationNormalized} _from
* @param {NavigationGuardNext} next
* @return {Promise<void>}
*/
export const isAuthenticated: NavigationGuard = async (
_to,
_from,
next
): Promise<void> => {
if (!await session().isAuthenticated()) {
next({
name: SIGN_IN_ROUTE
})
} else {
next()
}
}
|
Nice to have! |
Is this still not supported in Vue router? |
What problem does this feature solve?
This will allow splitting guard logic in smaller functions and making it easy to chain them. It's similar to express middlewares
What does the proposed API look like?
current solution to this: https://www.npmjs.com/package/vue-router-multiguard
Edit: Supporting arrays for in-component guards seems unnecessary as a component guard is specific to a component, they are not reused. On top of that, the typing of
this
would probably break so I removed them from the proposal.The text was updated successfully, but these errors were encountered: