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

dan*_*tin 7 vue.js vue-router vuejs2

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

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

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

Alb*_*inR 19

路由元字段为我解决了这个问题:

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


Edi*_*gic 12

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

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
                },
            ]
        },
    ],
});
Run Code Online (Sandbox Code Playgroud)

主视图将只有一个路由器视图组件,因此可以在没有导航栏的情况下显示登录视图组件。

<!-- App -->
<v-app>
    <v-content>
        <router-view> </router-view>
    </v-content>
</v-app>
Run Code Online (Sandbox Code Playgroud)

管理 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>
Run Code Online (Sandbox Code Playgroud)

然后,AdminHomeView 将被注入到管理外壳视图的嵌套路由器视图中。


Tom*_*myF 8

与 @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
  },
},
Run Code Online (Sandbox Code Playgroud)

  • 此方法不会在路线更改时重新呈现导航栏(可通过在创建或安装的挂钩中记录导航栏中的内容来验证)。导航栏以及计算属性位于“&lt;router-view/&gt;”之外,因此路由更改不会导致重新渲染。如果您是这样,您应该分享您的代码,以便我们可以尝试帮助识别问题@danmartin (2认同)

Ohi*_*hen 5

我们可以通过使用 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
Run Code Online (Sandbox Code Playgroud)

我的 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>
Run Code Online (Sandbox Code Playgroud)