解决Vue导航栏路由跳转,浏览器刷新后导航块高亮消失

最近前端项目上手没多久,就踩了一个小坑,一开始感觉还整挺好,随便点了点,,结果....

 手欠刷新了一下浏览器,就发现对应的导航块高亮消失

 这是怎么回事儿捏?代码如下 :

<el-menu
          :default-active="onRoutes"  //根据返回路由的index 高亮
          class="el-menu-vertical-demo"
          background-color="#4a4d50"
          text-color="#fff"
          active-text-color="#00ffff"
          :collapse="isCollapse"
          :collapse-transition="false"
          router
        >
          <!-- 一级菜单 -->
          <el-menu-item
            v-for="menu in menuList" // 遍历 menuList
            :key="menu.path"
            :index="menu.path" // 用path作下标
          >
            <!-- 图标 根据对应的menu.id获取对应的图标 -->
            <i :class="iconsObject[menu.id]"></i>
            <!-- 模板区 -->
            <template slot="title">
              <span>{{ menu.menuname }}</span>
            </template>
            <!-- <el-menu-item>
            
            </el-menu-item> -->
          </el-menu-item>
        </el-menu>
      </el-aside>
      <!-- 主体 -->
      <el-main><router-view></router-view></el-main>
    </el-container>
  </el-container>
</template>

 
<script>
import { getMenuList } from "../api/home";
export default {
  data() {
    return {
      menuList: [
        { id: 1, menuname: "用户管理", path: "user" },
        { id: 2, menuname: "商品管理", path: "shop" },
        { id: 3, menuname: "订单管理", path: "order" },
        { id: 4, menuname: "数据统计", path: "data" },
      ],
      iconsObject: {
        1: "el-icon-s-custom",
        2: "el-icon-s-cooperation",
        3: "el-icon-s-order",
        4: "el-icon-s-data",
        5: "el-icon-setting",
      },
      // 是否折叠菜单
      isCollapse: false,
      // flag: "点我收起",
    };
  },
  computed: {
    // 动态返回对应的路由path
    onRoutes() {
      return this.$route.path;
    },
  },

找了半天发现,menuList中的 path 没有加 / ,修改后,问题解决

总结原因:由于 default-active 中 onRoutes计算属性返回的是带有 / 的path

而 index 绑定的是menuList中的path(无 / ),path不一致(判端不是同一个path)

导致浏览器刷新后,default-active无法根据对应path高亮显示

menuList: [
        { id: 1, menuname: "用户管理", path: "/user" },
        { id: 2, menuname: "商品管理", path: "/shop" },
        { id: 3, menuname: "订单管理", path: "/order" },
        { id: 4, menuname: "数据统计", path: "/data" },
      ],

### Vue3 路由跳转时保留导航栏的实现方法 在 Vue3 中,当执行路由跳转时,默认情况下整个视图区域会被重新渲染。如果需要在路由跳转过程中保留导航栏功能,则需确保导航栏组件独立于 `<router-view>` 渲染逻辑之外[^4]。 以下是具体的实现方式: --- #### 1. 导航栏放置位置调整 为了使导航栏不受路由变化影响,在模板结构中应将导航栏组件置于 `<router-view>` 外部。这样无论路由如何切换,导航栏始终存在并保持其状态[^3]。 示例代码如下: ```vue <template> <div id="app"> <!-- 导航栏 --> <NavComponent /> <!-- 主体内容区 --> <main> <RouterView /> </main> <!-- 底部栏(可选) --> <FooterComponent /> </div> </template> <script setup lang="ts"> // 引入导航栏和底部栏组件 import NavComponent from &#39;./components/NavComponent.vue&#39;; import FooterComponent from &#39;./components/FooterComponent.vue&#39;; </script> ``` 在这个例子中: - `NavComponent` 是导航栏组件。 - `<RouterView />` 是用于显示当前路由对应的内容区域。 - 此布局确保了即使路由发生变化,导航栏也不会被重新加载或销毁。 --- #### 2. 使用 `key` 属性解决页面不刷新问题 某些场景下可能会遇到路由跳转URL 已经改变但页面未更新的情况。此时可通过为 `<RouterView>` 动态绑定唯一的 `key` 来强制触发组件重渲染[^4]。 示例代码如下: ```vue <template> <div id="app"> <!-- 导航栏 --> <NavComponent /> <!-- 主体内容区 --> <main> <RouterView :key="currentRouteKey" /> </main> <!-- 底部栏(可选) --> <FooterComponent /> </div> </template> <script setup lang="ts"> import { computed } from &#39;vue&#39;; import { useRoute } from &#39;vue-router&#39;; // 获取当前路由实例 const route = useRoute(); // 计算唯一 key 值 const currentRouteKey = computed(() => `${route.fullPath}-${Math.random()}`); </script> ``` 这里的关键在于每次计算都会生成一个新的随机数附加到路由路径后面作为 `key`,从而保证即使相同路径下的参数发生变更也能正确触发组件更新[^4]。 --- #### 3. 状态管理与导航栏同步 如果导航栏的状态依赖于当前路由信息(如高亮菜单项),可以通过监听 `$route` 的变化来动态维护这些状态[^2]。 示例代码如下: ```typescript <script setup lang="ts"> import { onMounted, watchEffect } from &#39;vue&#39;; import { useRoute } from &#39;vue-router&#39;; const route = useRoute(); let activeIndex = &#39;&#39;; onMounted(() => { // 初始化激活索引 setActiveIndex(route.path); }); watchEffect(() => { // 监听路由变化并更新激活索引 setActiveIndex(route.path); }); function setActiveIndex(path: string): void { switch (path) { case &#39;/home&#39;: activeIndex = &#39;Home&#39;; break; case &#39;/about&#39;: activeIndex = &#39;About&#39;; break; default: activeIndex = &#39;&#39;; } sessionStorage.setItem(&#39;active_index&#39;, activeIndex); // 存储至 session } </script> ``` 随后可在导航栏组件内部读取该存储值以决定哪个菜单项处于活动状态[^2]。 --- #### 4. 配置路由守卫保障体验一致性 为了避免非法访问以及提升用户体验的一致性,建议配置全局前置守卫 (`beforeEach`) 对不同用户的权限进行校验[^1]。 示例代码如下: ```javascript import { createRouter, createWebHistory } from &#39;vue-router&#39;; const routes = [ { path: &#39;/&#39;, component: () => import(&#39;@/views/Home.vue&#39;) }, { path: &#39;/login&#39;, component: () => import(&#39;@/views/Login.vue&#39;) }, ]; const router = createRouter({ history: createWebHistory(), routes, }); router.beforeEach((to, _, next) => { if (to.path === &#39;/login&#39;) { return next(); // 登录页直接放行 } const isLoggedIn = !!sessionStorage.getItem(&#39;login_right&#39;); if (!isLoggedIn) { return next(&#39;/login&#39;); // 用户未登录则跳转至登录页 } next(); // 合法请求继续前进 }); ``` 上述代码片段展示了如何利用路由守卫保护敏感资源的同时不影响其他部分正常运作[^1]。 --- ### 总结 综上所述,要在 Vue3 中实现路由跳转时保留导航栏功能,主要涉及以下几个方面: 1.导航栏移出 `<RouterView>` 区域; 2. 利用 `key` 属性解决潜在的页面不刷新问题; 3. 维护好导航栏状态并与当前路由紧密关联; 4. 设置合理的路由守卫机制增强应用健壮性和安全性。 通过以上措施即可达成目标,并提供流畅一致的操作感受给最终用户。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值