<router-view>标签;meta的 keepAlive与auth;

文章介绍了<router-view>在Vue项目中的核心作用,包括组件嵌套、路由配置(如keep-alive和authmeta)以及导航栏的继承。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<router-view>的含义: 此标签的作用就是显示当前路由级别下一级的页面。就比如说App.vue是根组件,在它的<template>标签里使用<router-view>,而且配置好路由的情况下,就能在浏览器上显示子组件的效果;子组件要想在页面中显示出来,一定要留好<router-view>容器,不然显示不出来;
如果这个子组件路由还有孩子路由,那也需要在子组件的<template>标签里使用<router-view>,这样就能在页面上显示子组件的孩子组件的效果;

在根组件App.vue的<template>里加<router-view/>,因为已经在index.js里配置好路由所以可以显示出子组件首页path: '/'页面或者登陆后显示的path: '/Home'页面;因为path: '/download-show'页面作为/Home的孩子页面,在子组件/Home<template>标签里使用了<router-view>,所以可以在页面上显示子组件的孩子组件内容;(可以实现比如我在子组件/Home里加导航栏的效果,然后它的孩子组件只要配置完路由就可以继承导航栏的效果,这篇点击后跳转到路由配置的页面;点击跳转后页面导航栏不改变样式与功能(路由位置区别)

一、根目录App.vue:

<template>
  <router-view/>
</template>

二、路由index.js:

const routes = [
   {
    path: '/',
    name: 'Index',
    component: () => import(/* webpackChunkName: "about" */ '../views/index/Index.vue'),
    meta:{
      keepAlive:true
    },

    children:[
    ]
  },
    {
    path: '/Home',
    name: 'Home',
    meta: {auth: true},
    component: Home,
    children:[
    {
        path: '/download-show',
        name: 'DownLoadShow',
        component: () => import(/* webpackChunkName: "about" */ '../views/downLoad/DownLoadShow.vue'),

      },
    ]
  },
]

(1)meta :在 Vue Router 中,meta 字段通常用于为路由定义自定义信息。这些信息不会直接影响路由的行为,但可以被用来在路由守卫(route guards)、导航守卫(navigation guards)或组件内部做出决策。
(2) meta: { keepAlive: true }: 是 Vue.js(特别是在 Vue Router 中)里用于路由元信息(route meta)的一个配置。这里的 keepAlive 不是一个标准的 Vue Router 属性,但它经常被用在结合 Vue 的 <keep-alive> 组件来缓存不活动的组件实例,而不是销毁它们。当你在 Vue Router 的路由配置中设置 meta: { keepAlive: true },你可以结合 <keep-alive> 组件来使得该路由对应的组件在切换路由时保持其状态,而不是被重新创建。

<template>  
  <div id="app">  
    <router-view v-if="$route.meta.keepAlive"></router-view>  
    <keep-alive>  
      <router-view v-if="!$route.meta.keepAlive"></router-view>  
    </keep-alive>  
  </div>  
</template>

在上面的例子中,只有当路由的 meta 中 keepAlive 为 false 时,<router-view> 才会被包裹在 <keep-alive> 中。这样,对于 meta: { keepAlive: true } 的路由,其组件实例就不会被缓存;而对于其他路由,其组件实例则会被缓存。
但通常,会看到更简单的用法,直接将需要缓存的路由的 <router-view> 包裹在 <keep-alive> 中,然后基于路由的 meta.keepAlive 属性来决定是否激活组件的缓存。
(3)meta: { auth: true }:这样的配置意味着为某个路由定义了一个 auth 元信息,其值为 true。这样的配置通常用于表示该路由需要用户认证才能访问。
例如,你可能有一个后台管理页面,这个页面需要用户登录后才能访问。你可以在这个路由的 meta 中设置 auth: true,然后在全局前置守卫(beforeEach guard)中检查这个值,如果用户未登录则重定向到登录页面。

const router = new VueRouter({  
  routes: [  
    {  
      path: '/admin',  
      component: Admin,  
      meta: { auth: true }  
    },  
    // 其他路由...  
  ]  
});  
  
router.beforeEach((to, from, next) => {  
  if (to.matched.some(record => record.meta.auth)) {  
    // 这个路由需要认证  
    // 检查用户是否已登录  
    // 假设有一个全局状态管理对象 store,其中有一个 isLoggedIn 属性  
    if (!store.state.isLoggedIn) {  
      // 用户未登录,重定向到登录页面  
      next({  
        path: '/login',  
        query: { redirect: to.fullPath }  
      });  
    } else {  
      next(); // 确保一定要调用 next()  
    }  
  } else {  
    next(); // 确保一定要调用 next()  
  }  
});

在上面的代码中,beforeEach 守卫检查即将进入的路由 to 是否有 meta.auth 设置为 true 的记录。如果有,并且用户未登录(store.state.isLoggedIn 为 false),则用户会被重定向到登录页面。
这样的设计模式可以帮助你实现基于路由的权限控制,使得只有经过认证的用户才能访问特定的页面或资源。

三、Home.vue

<template>
	<div class="home">
      <router-view/>
    </div>
</template>

感谢:
原文链接:https://blog.csdn.net/a1598452168YY/article/details/128153267

import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router' import { useAuthStore } from '@/stores/auth' import { useTagsViewStore } from '@/stores/tagsView' // 定义路由元信息类型 declare module 'vue-router' { interface RouteMeta { isShow?: boolean title?: string icon?: string roles?: string[] // 添加角色权限控制 } } // 公共路由(无需登录) export const constantRoutes: RouteRecordRaw[] = [ { path: '/login', name: 'login', component: () => import('@/views/LoginView.vue'), meta: { title: '登录', isShow: false } }, { path: '/403', name: 'forbidden', component: () => import('@/views/ForbiddenView.vue'), meta: { title: '无权限', isShow: false } }, { path: '/:pathMatch(.*)*', redirect: '/404', meta: { isShow: false} } ] // 异步路由(需要权限控制) export const asyncRoutes: RouteRecordRaw[] = [ { path: '/', redirect: '/flow', component: () => import('@/layout/MainLayout.vue'), meta: { requiresAuth: true }, children: [ { path: '/flow', name: 'flow', component: () => import('@/views/ProcessFlow.vue'), meta: { isShow: true, title: 'Flow', icon: 'Menu', roles: ['user', 'admin'] // 允许用户和管理员访问 } }, { path: '/viewList', name: 'viewList', meta: { isShow: true, title: 'OverView', icon: 'List', roles: ['user', 'admin'] // 允许用户和管理员访问 }, children: [ { path: '/viewList/ocrList', name: 'ocrList', component: () => import('@/views/OCRDecView.vue'), meta: { title: 'OCR', icon: 'Filter', roles: ['user', 'admin'] // 允许用户和管理员访问 } }, { path: '/viewList/orderDetails', name: 'orderDetails', component: () => import('@/views/MaterialOrderDetailsView.vue'), meta: { title: 'OrderDetails', icon: 'Filter', roles: ['user', 'admin'] // 允许用户和管理员访问 } } ] }, { path: '/config', name: 'config', meta: { isShow: true, title: 'Config', icon: 'Setting', roles: ['admin'] // 仅管理员可访问 }, children: [ { path: '/config/users', name: 'userConfig', component: () => import('@/views/UserManagement.vue'), meta: { title: 'Users', icon: 'User', roles: ['admin'] // 仅管理员可访问 } }, { path: '/config/materialBase', name: 'materialBase', component: () => import('@/views/MaterialBase.vue'), meta: { title: 'Materials', icon: 'Plus', roles: ['admin'] // 仅管理员可访问 } }, { path: '/config/materialOrder', name: 'materialOrder', component: () => import('@/views/MaterialOrder.vue'), meta: { title: 'Orders', icon: 'Plus', roles: ['admin'] // 仅管理员可访问 } }, { path: '/config/materialFormat', name: 'materialFormat', component: () => import('@/views/MaterialFormat.vue'), meta: { title: 'Formats', icon: 'Brush', roles: ['admin'] // 仅管理员可访问 } } ] } ] } ] const router = createRouter({ history: createWebHistory(), routes: constantRoutes }) // 路由守卫 - 权限控制 router.beforeEach(async (to,from) => { console.log(`[路由守卫] 从 ${from.path} 导航到 ${to.path}`) const authStore = useAuthStore() // 无需认证的页面 if (!to.meta.requiresAuth) return true // 检查登录状态 if (!authStore.token) { // 保存目标路径以便登录后重定向 return { path: '/login', query: { redirect: to.fullPath } } } // 已登录但未初始化用户信息 if (!authStore.isInitialized) { try { await authStore.initialize() // 初始化后重定向到原始请求 return { ...to, replace: true } } catch (error) { authStore.logout() return '/login' } } // 检查权限 if (to.meta.roles && !authStore.hasPermission(to.meta.roles)) { return '/403' // 无权限页面 } return true }) router.afterEach((to) => { const tagsViewStore = useTagsViewStore() if (!to.meta.noTagsView) tagsViewStore.addView(to) }) export default router vue-router.mjs:1611 Uncaught RangeError: Maximum call stack size exceeded at vue-router.mjs:1611:47 at Array.find (<anonymous>) at Object.resolve (vue-router.mjs:1611:32) at resolve (vue-router.mjs:3206:38) at pushWithRedirect (vue-router.mjs:3295:51) at pushWithRedirect (vue-router.mjs:3303:20) at pushWithRedirect (vue-router.mjs:3303:20) at pushWithRedirect (vue-router.mjs:3303:20) at pushWithRedirect (vue-router.mjs:3303:20) at pushWithRedirect (vue-router.mjs:3303:20)
最新发布
08-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值