VueJs-如何在某些路线上隐藏全局组件(例如navbar)?

时间:2019-10-29 21:34:13

标签: vue.js vuejs2 vue-router

因此,我的vuejs SPA上的绝大多数视图在顶部都有一个导航栏组件。但是,某些选择视图(例如登录名)不应显示此内容。

我的解决方法是导入导航栏,并在需要时将其单独添加到每个视图,但是现在我可以看到,从一个视图转到另一个视图时,它会引起奇怪的闪烁-大概是因为导航栏组件已被删除,并且立即重新添加。这似乎是错误的。

我假设有某种方法可以在App.vue中添加导航栏组件,但有条件地使用vue-router将其隐藏在某些路由上?最佳做法是什么?

6 个答案:

答案 0 :(得分:3)

常见方法是使用嵌套路由。这是我的一个项目的示例:

const router = new Router({
    mode: 'history',
    base: process.env.BASE_URL,
    routes: [
        {
            path: '/login',
            name: 'login',
            component: LoginView,
        },
        {
            path: '/admin',
            name: 'admin',
            component: AdminShell,
            children: [
                {
                    path: 'home',
                    name: 'admin_home',
                    component: AdminHomeView
                },
            ]
        },
    ],
});

主视图仅具有路由器视图组件,因此登录视图组件无需导航栏即可显示。

<!-- App -->
<v-app>
    <v-content>
        <router-view> </router-view>
    </v-content>
</v-app>

Admin shell将被注入到主视图中,其中将包含导航栏,侧边栏以及所需的内容。

<!-- Admin shell -->
<v-container fill-height>
    <v-toolbar color="blue darken-3" dark app :clipped-left="$vuetify.breakpoint.mdAndUp" fixed>
        <v-toolbar-title style="width: 300px" class="ml-0 pl-3">
            <v-toolbar-side-icon @click.stop="drawer = !drawer"></v-toolbar-side-icon>
            <span class="hidden-sm-and-down">Admin</span>
        </v-toolbar-title>
        <v-spacer></v-spacer>
        <UserInfo></UserInfo>
    </v-toolbar>

    <!-- Nested route -->
    <router-view></router-view>
</v-container>

然后,将AdminHomeView注入admin shell视图的嵌套路由器视图中。

答案 1 :(得分:3)

Route Meta Fields 为我解决了这个问题:

//router.js
{
 path: '/login',
 name: 'login',
 component: () => import(/* webpackChunkName: 'login' */ '@/components/Login.vue'),
 meta: {
  hideNavbar: true,
 }
}
//App.vue
<Navbar v-if="!$route.meta.hideNavbar" />

答案 2 :(得分:2)

我们可以通过使用v-if指令检查当前路线的名称来有条件地渲染组件。我在最近的项目中使用了这个。

我的路线index.js文件

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import Login from '../views/Login.vue'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'home',
    component: Home
  },
  {
    path: '/login',
    name: 'login',
    component: Login
  },
  {
    path: '/register',
    name: 'register',
    component: Register
  }  
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

我的App.vue文件

<template>
    <div id="app">

/* Note that this takes an array of route names, so you can simply pass in
the name of the route you don't want this component to be displayed on */

        <navbar v-if="!['login', 'register', 'help'].includes($route.name)" />
    
        <main>
            <router-view />
        </main>
    
        <appfooter v-if="!['login', 'register'].includes($route.name)"/>
    
    </div>
    </template>

答案 3 :(得分:0)

相对于@Edins嵌套路由方法,我更喜欢在主视图中使用条件渲染的组件。

Vue通过Vuex提供了一个出色的全局状态存储,这也使得这一操作变得异常简单。

经典示例是仅在用户登录后才具有导航栏。
因此,您可以在状态存储中跟踪登录状态,然后在主视图(或App.vue)中使用经过计算的getter:

<template>
  <navbar v-if="isAuthenticated"/>
  <router-view/>
</template>

export default {
name: 'App',
computed: { 
  isAuthenticated() {
    return this.$store.getters.isAuthenticated
  },
},

答案 4 :(得分:0)

在路由器中-> index.js 编写子路由并在父级中 - 那时写入的任何全局组件, 并在孩子们写下我们想要展示的地方

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes: [
    { path: "/", redirect: "/login" },
    { path: "/registration", component: registration },

    {
      path: "/home",
      component: navbar,
      children: [
        {
          path: "/home",
          name: "home",
          component: () => import("../views/Home.vue"),
        },
        {
          path: "/notes",
          name: "notes",
          component: () => import("../views/notes/Index.vue"),
        },
        {
          path: "/notes/create",
          name: "notescreate",
          component: () => import("../views/notes/Create.vue"),
        },
        {
          path: "/notes/edit/:id",
          name: "notesedit",
          component: () => import("../views/notes/Edit.vue"),
        },
        { path: "/myposts", component: myPosts },
        { path: "/allposts", component: allPosts },
        { path: "/create", component: create },
        { path: "/edit/:id", component: edit },
      ],
    },
    {
      path: "/login",
      name: "login",
      component: () => import("../views/Login.vue"),
    },
  ],
});

别忘了在 app.vue 中编写

没有路由器视图 - 它不会工作

答案 5 :(得分:0)

我知道它很旧,但我使用了不同的方式。

只需观察路线名称的变化即可。我喜欢在路线中使用 auth.loginauth.register

<v-app-bar v-if="!currentRouteName.startsWith('auth')"></v-app-bar>

然后:

data() {
    return{
        currentRouteName: 'home',
    }
},
watch:{
    ['$route.name'](route) {
        this.currentRouteName = route
    }
}