Hello,
I'm not sure if this the correct way of thinking - but I want one of my components to be disabled or deactivated on some routes.
So here's my routes.
router.map({
'/': { component: ProductsView },
'/auth/login': { component: LoginView },
'/auth/register': { component: RegisterView },
'/products': { component: ProductsView },
'/products/:product': { component: ProductView },
'/categories': { component: CategoriesView },
'/categories/:category': { component: CategoryView },
'*': { component: NotFoundView }
});
My main template file looks like so:
<!DOCTYPE html>
<html lang="en" id="app">
<head>
<!-- Head Contents -->
</head>
<body>
<header>
<!-- Header Contents -->
<navigation></navigation>
</header>
<div class="container">
<router-view></router-view>
</div>
</body>
</html>
When I'm on either the /auth/login or /auth/register routes - I do not want my navigation component to appear.
How can I achieve this?
@JoeDawson I'm sure Vue provides many mechanisms to accomplish this. I believe the v-if or v-show directives should be used since this is a conditional rendering matter.
Now for the conditional expression to use with those directives you can utilize the $route.path or $route.name which are made available to each component by vue-router. This is documented here: http://vuejs.github.io/vue-router/en/route.html
First I would add names to my routes:
router.map({
// ...
'/auth/login': { name: 'login', component: LoginView },
'/auth/register': { name: 'register', component: RegisterView },
// ...
});
Then you can just conditionally display the navigation based on the current route name:
<navigation v-if="['login', 'register'].indexOf($route.name) > -1"></navigation>
This is just one way, and I'm sure it can be cleaned up a bit. Though I would like to know if there is a potential _best practice_ way to do this since I imagine this is a common pattern.
Maybe @yyx990803 can enlighten us on the matter.
@amirrustam I approached it a little differently in the end - I simply added a class to the body if the current route matched either /auth/login or /auth/register then used CSS to hide the component. Not the best solution I guess, but a working one.
<body :class="{ 'auth': $route.path==='/auth/register' || $route.path==='/auth/login' }">
Cool. is their a best practice to this, i couldn't find anything in the vue cookbook.
This will also work
<navigation v-if="['login', 'register'].includes($route.name)"></navigation>
What are the best practices for hiding/disabling a component on some routes?
In the nav component listen to the route changes to update a flag whether the nav will be shown or hidden, you may check with route name or path:
note: the following example uses typescript:
export const router = new Router({
mode: "history",
routes: [
{ name: "home", path: "/", component: Home },
{ name: "login", path: "/login", component: LoginView }
]
});
<nav v-if="showHeader">
...
</nav>
@Watch("$route", { immediate: true })
OnRouteChange(route: Route) {
if (route.name == "login" || route.name == "signup") {
this.showHeader = false;
} else {
this.showHeader = true;
}
}
Route meta fields provide yet another option:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
meta: { hideNavigation: true }
}
]
})
<navigation v-if="!$route.meta.hideNavigation" />
This question covers a useful thing to know in general, however if you want to show/hide certain main components like a header or footer, the best way is to simply create multiple layouts that include the components you want.
get current route path using this.$route.path
<navigation v-if="showNavigation"></navigation>
data() {
this.$route.path === '/' ? this.showNavigation = false : this.showNavigation = true
}
Most helpful comment
@JoeDawson I'm sure Vue provides many mechanisms to accomplish this. I believe the
v-iforv-showdirectives should be used since this is a conditional rendering matter.Now for the conditional expression to use with those directives you can utilize the
$route.pathor$route.namewhich are made available to each component by vue-router. This is documented here: http://vuejs.github.io/vue-router/en/route.htmlFirst I would add names to my routes:
Then you can just conditionally display the navigation based on the current route name:
This is just one way, and I'm sure it can be cleaned up a bit. Though I would like to know if there is a potential _best practice_ way to do this since I imagine this is a common pattern.
Maybe @yyx990803 can enlighten us on the matter.