解决Vue报错:Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location...

一、重复点击导航时,控制台出现报错 ,虽然不影响功能使用,但也不能坐视不管。

解决方案:

方案一:只需在 router 文件夹下,添加如下代码:
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '@/views/Home'
import Main from '@/views/Main'
import User from '@/views/User'
Vue.use(VueRouter)

// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来

// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
  // //主路由
  {
    path: '/',
    component: Main,
    redirect:"home",
    children: [//子路由,嵌套路由
      {
        path: 'home',
        component: Home
      },
      {
        path: 'user',
        component: User
      },
      {
        path: "/acl/user",
        name: "user",
        title: "用户管理",
        icon: "setting",
        component: () => import("@/views/acl/user/List.vue"),
      },
      {
        path: "/acl/role",
        name: "role",
        title: "角色管理",
        icon: "setting",
        component: () => import("@/views/acl/role/List.vue"),
      },
      {
        path: "/acl/menu",
        name: "menu",
        title: "菜单管理",
        icon: "setting",
        component: () => import("@/views/acl/menu/List.vue"),
      }
      // ,
      // {
      //   title: "权限管理",
      //   icon: "s-order",
      //   name: "/acl",
      //   path: '/acl',
      //   children: [
      //     {
      //       path: "/user1",
      //       name: "user",
      //       title: "用户管理",
      //       icon: "setting",
      //       component: () => import("@/views/acl/user/List.vue"),
      //     },
      //     {
      //       path: "/acl/role",
      //       name: "role",
      //       title: "角色管理",
      //       icon: "setting",
      //       component: () => import("@/views/acl/role/List.vue"),
      //     },
      //     {
      //       path: "/acl/menu",
      //       name: "menu",
      //       title: "菜单管理",
      //       icon: "setting",
      //       component: () => import("@/views/acl/menu/List.vue"),
      //     },
      //   ],
      // },
    ]
  },



]

// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
  routes // (缩写) 相当于 routes: routes
})

// 4. 创建和挂载根实例。(在main.js里继续挂载)
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能

// 解决重复点击导航时,控制台出现报错
const VueRouterPush = VueRouter.prototype.push
VueRouter.prototype.push = function push (to) {
  return VueRouterPush.call(this, to).catch(err => err)
}
 
export default router
方案二、使用 catch 方法捕获 router.push 异常。
this.$router.push(route).catch(err => {
  console.log('输出报错',err)
})
方案三、在跳转时,判断是否跳转路由和当前路由是否一致,避免重复跳转产生问题。

index路由文件

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '@/views/Home'
import Main from '@/views/Main'
import User from '@/views/User'
Vue.use(VueRouter)

// 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来

// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
  // //主路由
  {
    path: '/',
    component: Main,
    redirect:"home",
    children: [//子路由,嵌套路由
      {
        path: 'home',
        component: Home
      },
      {
        path: 'user',
        component: User
      },
      {
        path: "/acl/user",
        name: "user",
        title: "用户管理",
        icon: "setting",
        component: () => import("@/views/acl/user/List.vue"),
      },
      {
        path: "/acl/role",
        name: "role",
        title: "角色管理",
        icon: "setting",
        component: () => import("@/views/acl/role/List.vue"),
      },
      {
        path: "/acl/menu",
        name: "menu",
        title: "菜单管理",
        icon: "setting",
        component: () => import("@/views/acl/menu/List.vue"),
      }
      // ,
      // {
      //   title: "权限管理",
      //   icon: "s-order",
      //   name: "/acl",
      //   path: '/acl',
      //   children: [
      //     {
      //       path: "/user1",
      //       name: "user",
      //       title: "用户管理",
      //       icon: "setting",
      //       component: () => import("@/views/acl/user/List.vue"),
      //     },
      //     {
      //       path: "/acl/role",
      //       name: "role",
      //       title: "角色管理",
      //       icon: "setting",
      //       component: () => import("@/views/acl/role/List.vue"),
      //     },
      //     {
      //       path: "/acl/menu",
      //       name: "menu",
      //       title: "菜单管理",
      //       icon: "setting",
      //       component: () => import("@/views/acl/menu/List.vue"),
      //     },
      //   ],
      // },
    ]
  },



]

// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
const router = new VueRouter({
  routes // (缩写) 相当于 routes: routes
})

// 4. 创建和挂载根实例。(在main.js里继续挂载)
// 记得要通过 router 配置参数注入路由,
// 从而让整个应用都有路由功能

// 解决重复点击导航时,控制台出现报错
// const VueRouterPush = VueRouter.prototype.push
// VueRouter.prototype.push = function push (to) {
//   return VueRouterPush.call(this, to).catch(err => err)
// }
 
export default router

菜单组件

<template>
  <div class="hello">
    <!-- <el-radio-group v-model="isCollapse" style="margin-bottom: 20px">
      <el-radio-button :label="false">展开</el-radio-button>
      <el-radio-button :label="true">收起</el-radio-button>
    </el-radio-group> -->

    <el-menu
      default-active="1-4-1"
      class="el-menu-vertical-demo"
      @open="handleOpen"
      @close="handleClose"
      :collapse="isCollapse"
      background-color="#545c64"
      text-color="#fff"
      active-text-color="#ffd04b"
    >
      <!-- 循环菜单数据 -->
      <label v-for="item in menuData" :key="item.name">
        <!-- 判断是否有子菜单,如果有就创建submenu,没有就创建menu-item -->
        <el-submenu
          :index="item.name"
          v-if="item.children"
          @click="clickMenu(item)"
        >
          <template slot="title">
            <i :class="`el-icon-${item.icon}`"></i>
            <span>{{ item.title }}</span>
          </template>
          <label>
            <!-- 自己调用自己 -->
            <CommonAsideMenuTRee
              :menuData="item.children"
            ></CommonAsideMenuTRee>
          </label>
        </el-submenu>
        <el-menu-item v-else :index="item.name" @click="clickMenu(item)">
          <template slot="title">
            <i :class="`el-icon-${item.icon}`"></i>
            <span>{{ item.title }}</span>
          </template>
        </el-menu-item>
      </label>
      <!-- <el-menu-item
        v-for="item in noChildren"
        :key="item.name"
        index="item.name"
      >
        <i :class="`el-icon-${item.icon}`"></i>
        <span slot="title">{{ item.label }}</span>
      </el-menu-item>

      <el-submenu
        v-for="item in hasChildren"
        :key="item.name"
        index="item.name"
      >
        <template slot="title">
          <i :class="`el-icon-${item.icon}`"></i>
          <span slot="title">{{ item.label }}</span>
        </template>
        <el-menu-item-group v-for="child in item.children" :key="child.name">
          <el-menu-item index="child.name">{{ child.label }}</el-menu-item>
        </el-menu-item-group>
      </el-submenu>   -->
    </el-menu>
  </div>
</template>

<script>
import CommonAsideMenuTRee from "@/components/CommonAsideMenuTRee.vue";
export default {
  name: "CommonAsideMenuTRee",
  components: {
    CommonAsideMenuTRee,
  },
  props: {
    menuData: {
      type: Array,
    },
  },
  data() {
    return {
      isCollapse: false,
      menuList1: [
        {
          path: "/user",
          name: "user",
          label: "用户管理",
          icon: "user",
          url: "UserManage/UserManage",
        },
        {
          path: "/",
          name: "Main",
          label: "首页",
          icon: "s-home",
          url: "Main/Main",
        },
        {
          label: "权限管理",
          icon: "s-order",
          name: "acl",
          component: "",
          path: "",
          children: [
            {
              path: "/acl/user",
              name: "user",
              label: "用户管理",
              icon: "setting",
              component: () => import("@/views/acl/user/List.vue"),
            },
            {
              path: "/acl/role",
              name: "role",
              label: "角色管理",
              icon: "setting",
              component: () => import("@/views/acl/role/List.vue"),
            },
            {
              path: "/acl/menu",
              name: "menu",
              label: "菜单管理",
              icon: "setting",
              component: () => import("@/views/acl/menu/List.vue"),
            },
          ],
        },
      ],
    };
  },
  computed: {
    //没有子菜单
    noChildren() {
      return this.menuList.filter((item) => !item.children);
    },
    //有子菜单
    hasChildren() {
      return this.menuList.filter((item) => {
        return item.children;
      });
    },
  },
  methods: {
    handleOpen(key, keyPath) {
      console.log(key, keyPath);
    },
    handleClose(key, keyPath) {
      console.log(key, keyPath);
    },
    //点击菜单,路由跳转
    clickMenu(item) {
      console.log("this.$route.path ==== " +this.$route.path);
      console.log("item.path =========== "+ item.path);
      console.log("-------------------------------------------------");
      // 判断是否跳转路由和当前路由是否一致,避免重复跳转产生问题
      // 当页面的路由和跳转的路由不一致才跳转
      if(this.$route.path !== item.path && !(this.$route.path === '/home' && item.path === '/')){
        this.$router.push(item.path)
      }
  
    },
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="less" scoped>
.el-menu {
  // height: 100vh;
  border-right: none;
}
</style>

修改后的截图

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值