首页 > 其他分享 >解决Vue报错:Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location

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

时间:2022-12-17 23:23:37浏览次数:57  
标签:Vue views component redundant acl 报错 import path 路由

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

解决方案:

方案一:只需在 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>

修改后的截图

 

标签:Vue,views,component,redundant,acl,报错,import,path,路由
From: https://www.cnblogs.com/konglxblog/p/16989780.html

相关文章

  • VUE组件
    9.Vue组件组件(Component)是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任......
  • VUE组件
    9.Vue组件组件(Component)是Vue.js最强大的功能之一。组件可以扩展HTML元素,封装可重用的代码。组件系统让我们可以用独立可复用的小组件来构建大型应用,几乎任意类型的应用......
  • Vue 中实现全局引入 scss 变量
    导读最终实现的效果是:在vue文件的style标签中以及其它scss文件中都可以直接使用全局配置的scss变量,不需要再导入对应的scss文件。目录结构src│App.vue│......
  • Vue的浏览器中的 webStorage
    Vue的浏览器中的 webStorage1:Api介绍/*webStorage存储内容大小一般支持5MB左右(不同浏览器可能还不一样)浏览器端通过Window.sessionStorage和Window.localStorage属性......
  • Vue 中的 Todo-list 案例
    Vue中的 Todo-list案例1:示例​​​​总结TodoList案例组件化编码流程:(1).拆分静态组件:组件要按照功能点拆分,命名不要与html元素冲突。(2).实现动态组件:考虑好数据的存......
  • Vue项目入门
    1安装VueMac版本安装:https://zhuanlan.zhihu.com/p/435312919Window版本安装:https://blog.csdn.net/weixin_43896253/article/details/116143031开发软件安装:VisualSt......
  • ThreadPoolExecutor创建线程池启动项目报错问题
    ThreadPoolExecutor创建线程,如下代码:ThreadPoolExecutorthreadPoolExecutor=newThreadPoolExecutor(Runtime.getRuntime().availableProcessors()+1,20,......
  • vue-template-admin 模板
    1.替换登录页的样式       ......
  • 一次性能调优记录:压测报错out of memory内存溢出【杭州多测师_王sir】【杭州多测师】
    一次性能调优记录:压测报错out of memory内存溢出1、首先这是一段压测的报错日志截图2、服务器的配置还不错,执行机全64核以上,运存256g以上,服务器80核,512g,所有机器线程数......
  • vue3项目,记录我是如何用1h实现产品预估1天工作量的界面需求
    最近在编写前端界面,硬是一人一周时间加班加点写完了一个项目的前端界面(一级菜单有12个页面+一个控制台大屏,二三级界面有N个),之前预估前端界面的编写需要一个月,我是自己......