【vue】导航栏变动后刷新router的几种方法

方法1:window.location.reload()

强制整页刷新

这种方法最为直接,但会中断当前的用户体验,有瞬间白屏。

方法2:使用hidden控制menu渲染

1、适合APP这种通过输入网址进入界面情况;

2、menu一般在login进入主页面后只加载一次不会频繁触发,所以onMounted中可以执行菜单显隐控制逻辑。

router/index.js

javascript 复制代码
import { createRouter, createWebHistory } from 'vue-router';
import Layout from '@/layout/index.vue';
import { useAppStore } from '../store';
import { invoke } from '@tauri-apps/api/core';

const router = createRouter({
  history: createWebHistory(import.meta.env.VITE_BASE_URL),
  routes: [
    {
      path: '/account/login',
      name: 'login',
      hidden: true,
      component: () => import('@/views/account/login.vue'),
    },
    {
      path: '/',
      component: Layout,
      redirect: '/account/login',
      children: [
        {
          path: 'dashboard',
          name: 'Home',
          component: () => import('@/views/entry/index.vue'),
          meta: {
            title: 'menu.home',
            icon: 'menu_home',
            affix: true,
          },
        },
      ],
    },
    {
      path: '/robot',
      component: Layout,
      children: [
        {
          path: 'robot',
          name: 'RobotManage', // 没有name面包屑不展示
          component: () => import('@/views/robot/index.vue'),
          meta: {
            title: 'menu.robot', // 各处导航标题
            icon: 'menu_robot',
          },
        },
      ],
    },
    {
      path: '/setting',
      component: Layout,
      redirect: '/setting/scene',
      children: [
        {
          path: 'scene',
          name: 'SceneManage',
          component: () => import('@/views/setting/scene/sceneManage/index.vue'),
          meta: {
            title: 'menu.config',
            icon: 'menu_setting',
          },
        },
      ],
    },
    {
      path: '/log',
      component: Layout,
      children: [
        {
          path: 'log',
          name: 'LogManage',
          component: () => import('@/views/log/index.vue'),
          meta: {
            title: 'menu.logs',
            icon: 'menu_log',
          },
        },
      ],
    },
    {
      path: '/map',
      component: Layout,
      children: [
        {
          path: 'map',
          name: 'MapManage',
          component: () => import('@/views/map/index.vue'),
          meta: {
            title: 'menu.design',
            icon: 'menu_map',
          },
        },
      ],
    },
    {
      path: '/404',
      component: () => import('@/views/404.vue'),
      hidden: true,
    },
    {
      path: '/:pathMatch(.*)*',
      redirect: '/404',
      hidden: true,
    },
  ],
});

export const resetRouter = () => {
  // console.log(router)
};

/**
 * 路由拦截设置
 *
 */
router.beforeEach(async (to, from, next) => {
  console.log('监测路由变化:从', from.path, '到', to.path);
  next();
  return;
});

export default router;

menu导航页面:

html 复制代码
<template>
  <el-scrollbar :height="props.height" id="router-menu">
    <!-- 必须添加background-color属性,因为收起菜单时 悬浮二级菜单默认为白色背景 需要重置 -->
    <el-menu
      :active-text-color="variables.menuActiveText"
      :background-color="variables.menuBg"
      :collapse="isCollapse"
      :collapse-transition="false"
      :default-active="activeMenu"
      :text-color="variables.menuText"
      :unique-opened="false"
      mode="vertical"
    >
      <item :base-path="route.path" :info="route" :key="route.path" v-for="route in routes" />
    </el-menu>
  </el-scrollbar>
</template>

<script setup>
import { onMounted, onUnmounted, ref, computed, inject } from 'vue';
import { useRouter, useRoute } from 'vue-router';
// import { onBeforeRouteUpdate } from 'vue-router'

import variables from '@/styles/variables.module.scss';
import Item from './Item.vue';

const props = defineProps({
  height: {
    type: String,
    default: '100%',
  },
  isCollapse: {
    type: Boolean,
    default: false,
  },
});

const routes = ref(useRouter().options.routes);
const route = useRoute();

const activeMenu = computed(() => {
  const { meta, path } = route;
  // if set path, the sidebar will highlight the path you set
  if (meta.activeMenu) {
    return meta.activeMenu;
  }
  return path;
});

const updateMenuRoutes = () => {
  routes.value.forEach(item => {
    if (item.path === '/robot' && localStorage.getItem('features') === 'emulator') {
      item.hidden = true;
    } else if (item.path === '/robot' && localStorage.getItem('features') !== 'emulator') {
      item.hidden = false;
    }
  });
};

onMounted(() => {
  updateMenuRoutes();
});
</script>
相关推荐
樊小肆1 小时前
# 你还在等DeepSeek官方 agent Harness‌? 来试试 DeepSeeker-Code吧
前端·人工智能·后端
樊小肆1 小时前
2568 万 token 才花 2 块 2:聊聊 DeepSeeker-Code 怎么吃满上下文缓存
前端·人工智能·后端
JarvanMo1 小时前
Flutter 3.47: material/cupertino终于解耦了
前端
郭邯2 小时前
一次「字符洁癖」引发的思考:我用 AI 写了个全角半角转换工具
前端
想要成为糕糕手2 小时前
🚀 在浏览器里跑 DeepSeek-R1?WebGPU 端侧推理实战(五)—— 中断、重置、缓存与流式生成
前端·react.js·llm
GuWenyue2 小时前
后端接口又双叒没写好?3 步搭建前端 Mock,从此告别"傻等后端"
前端·mocha
海兰2 小时前
【数据采集】开源的 Web 数据采集与处理Firecrawl(一)
前端·开源
vivo互联网技术2 小时前
从一键检测到 AI 修复:我们如何把无障碍检查做进研发流程
前端·人工智能
liuxiaocheng2 小时前
聊聊 Vercel AI SDK 的流式协议:前后端到底是怎么"边想边说"的
前端·后端
胡萝卜术2 小时前
在浏览器中跑 DeepSeek-R1:WebGPU 推理全流程深度解析
前端·javascript·面试