vue3+vue-router4:报错Uncaught (in promise) Error: Invalid navigation guard

这篇具有很好参考价值的文章主要介绍了vue3+vue-router4:报错Uncaught (in promise) Error: Invalid navigation guard。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

报错图示:

Error: Invalid navigation guard
Uncaught (in promise) Error: Invalid navigation guard
vue3+vue-router4:报错Uncaught (in promise) Error: Invalid navigation guard,微信公众号,Vant,Vue,vue.js,前端,javascript

错误影响描述:

配置开发、测试、生产时候,因为是公众号,所以想在开发环境下免鉴权,不走微信获取openid接口,pinia中定义好openid直接进入项目,遂遇此问题。
因为在async和await中使用,导致next()不能正确执行,查看源码,因为在非生产环境做了此限制,所以只要是生产环境就没问题,但是我就是要dev使用呀。

错误代码示例:
// vant4函数形式的组件
import '@/assets/js/vant4.js'
import '@/assets/css/main.css'
import { getQueryString } from '@/assets/js/common.js'
import { showToast } from 'vant'

import { createApp } from 'vue'
import App from './App.vue'
import router from '@/router/index'
// pinia 共享仓库
import { createPinia ,storeToRefs } from "pinia";
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
// 接口
import { getWechatInfoByCode ,getByOpenid } from '@/api/index'
import { useStore } from '@/store/index'

const pinia = createPinia()
const app = createApp(App)
// 数据持久化
pinia.use(piniaPluginPersistedstate);
// 环境变量挂在全局
app.config.globalProperties.$getEnv = import.meta.env

app.use(pinia)
app.use(router)
app.mount('#app')


// 路由守卫 start
router.beforeEach( async (to, from, next) => {
    const store = useStore();
    // 必须storeToRefs绑定否则拿不到最新值
    const { openid } = storeToRefs(store);
    const { VITE_HOST , VITE_APPID } = import.meta.env
    // 微信公众号appid-开发-基本配置中获取
    const appId = VITE_APPID
    // 获取code后再次跳转路径 window.location.href;例:www.baido.com/#/Home
    const toPath = VITE_HOST + '/#' + to.path
    // 核心步骤,获取code
    const hrefurl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + encodeURIComponent(toPath) + "&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
    // 从地址栏获取code
    const code = getQueryString('code')
    // 有openid就放行,单纯为了获取openid,无需关心是否登录,绑定等
    const haveOpenidPass = ['/bindAccount' , '/register']
    // 是否账号绑定了openid  
    const isBindAccount = async () => {
        const resGetInfo = await getByOpenid({ openid: openid.value })
        if(resGetInfo.code === 0){
            if(resGetInfo.data){
                // 已绑定
                store.setLoginInfo(resGetInfo.data)
                // dev test 环境都会跳转失效并报错,生产可以正常跳转无报错 !!!
                next()
            }else{
                // 未绑定 
                // 清空store用户信息
                store.setLoginInfo({
                    user:{
                        Uid:''
                    }
                })
                // contactUs 相当于注册,直接通过
                if(to.path == '/contactUs'){
                	// dev test 环境都会跳转失效并报错,生产可以正常跳转无报错 !!!
                    next()
                }else{
                    next({
                        path: '/register'
                    })
                }         
            }
        }else{
            // 请求失败,放行
            showToast(resGetInfo?.info || '请求失败!');
            next()
        }
    }

    /* 路由发生变化修改页面title */
    if (to.meta.title) {
        document.title = to.meta.title;
    }
    /* 判断该路由是否需要登录权限 */
    if (to.matched.some(record => record.meta.requireAuth)) {
        if (openid.value) {
            if(haveOpenidPass.includes(to.path)){
                next()
            }else{
            	// !!!错误的根源在此 !!!
                isBindAccount()
            } 
        } else { //openId不存在
            if (code) { //根据code获取openId
                const res = await getWechatInfoByCode({ code })
                if (res && res.code == 0) {
                    store.setOpenid(res.data.openid)
                    isBindAccount()
                } else {
                    showToast(res?.info || '请求失败!');
                }
            } else {  //获取code
                window.location.replace(hrefurl)
            }
        }
    } else {
        next()
    }
})
// 路由守卫 end

解决方式:

只需要给isBindAccount()函数调用时候加个return就行。

// vant4函数形式的组件
import '@/assets/js/vant4.js'
import '@/assets/css/main.css'
import { getQueryString } from '@/assets/js/common.js'
import { showToast } from 'vant'

import { createApp } from 'vue'
import App from './App.vue'
import router from '@/router/index'
// pinia 共享仓库
import { createPinia ,storeToRefs } from "pinia";
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
// 接口
import { getWechatInfoByCode ,getByOpenid } from '@/api/index'
import { useStore } from '@/store/index'

const pinia = createPinia()
const app = createApp(App)
// 数据持久化
pinia.use(piniaPluginPersistedstate);
// 环境变量挂在全局
app.config.globalProperties.$getEnv = import.meta.env

app.use(pinia)
app.use(router)
app.mount('#app')


// 路由守卫 start
router.beforeEach( async (to, from, next) => {
    const store = useStore();
    // 必须storeToRefs绑定否则拿不到最新值
    const { openid } = storeToRefs(store);
    const { VITE_HOST , VITE_APPID } = import.meta.env
    // 微信公众号appid-开发-基本配置中获取
    const appId = VITE_APPID
    // 获取code后再次跳转路径 window.location.href;例:www.baido.com/#/Home
    const toPath = VITE_HOST + '/#' + to.path
    // 核心步骤,获取code
    const hrefurl = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appId + "&redirect_uri=" + encodeURIComponent(toPath) + "&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect";
    // 从地址栏获取code
    const code = getQueryString('code')
    // 有openid就放行,单纯为了获取openid,无需关心是否登录,绑定等
    const haveOpenidPass = ['/bindAccount' , '/register']
    // 是否账号绑定了openid  
    const isBindAccount = async () => {
        const resGetInfo = await getByOpenid({ openid: openid.value })
        if(resGetInfo.code === 0){
            if(resGetInfo.data){
                // 已绑定
                store.setLoginInfo(resGetInfo.data)
                next()
            }else{
                // 未绑定 
                // 清空store用户信息
                store.setLoginInfo({
                    user:{
                        Uid:''
                    }
                })
                // contactUs 相当于注册,直接通过
                if(to.path == '/contactUs'){
                    next()
                }else{
                    next({
                        path: '/register'
                    })
                }         
            }
        }else{
            // 请求失败,放行
            showToast(resGetInfo?.info || '请求失败!');
            next()
        }
    }

    /* 路由发生变化修改页面title */
    if (to.meta.title) {
        document.title = to.meta.title;
    }
    /* 判断该路由是否需要登录权限 */
    if (to.matched.some(record => record.meta.requireAuth)) {
        if (openid.value) {
            if(haveOpenidPass.includes(to.path)){
                next()
            }else{
                // 处理非prod环境下,控制台异常,报错无法跳转问题
                return isBindAccount()
            } 
        } else { //openId不存在
            if (code) { //根据code获取openId
                const res = await getWechatInfoByCode({ code })
                if (res && res.code == 0) {
                    store.setOpenid(res.data.openid)
                    isBindAccount()
                } else {
                    showToast(res?.info || '请求失败!');
                }
            } else {  //获取code
                window.location.replace(hrefurl)
            }
        }
    } else {
        next()
    }
})
// 路由守卫 end

备注:

vue3的ref变量使用必须加.value,卧槽,反人类啊,开倒车!!!经常忘记,导致我疯狂debug文章来源地址https://www.toymoban.com/news/detail-581901.html

到了这里,关于vue3+vue-router4:报错Uncaught (in promise) Error: Invalid navigation guard的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Uncaught Error: [vue-router] “path“ is required in a route configuration 的解决方案

    其一、报错的代码信息为: Uncaught Error: [vue-router] “path“ is required in a route configuration 中文翻译: 未捕获的错误:[vue-router]“路径”在路由配置中是必需的 其二、报错的页面显示为: 看到提示,肯定是 vue-router 的 path 的原因报错; 其一、就是配置路由的时候 多加了一个花

    2024年02月10日
    浏览(46)
  • vue3 vite Uncaught (in promise) ReferenceError: Cannot access ‘xx‘ before initialization

    Uncaught (in promise) ReferenceError: Cannot access \\\'BasicForm\\\' before initialization这是 组件之间出现循环引用时导致,我们可以通过异步组件: defineAsyncComponent解决, 在VUE3的官网:https://cn.vuejs.org/guide/components/async.html#basic-usage。 直接引用官网提供的异步组件( defineAsyncComponent ),写法多种。以

    2024年02月12日
    浏览(71)
  • GET http://localhost:8080/xx/xx 404 (Not Found) 和Uncaught (in promise) Error: failed报错的原因

    这两天,我遇见了一个很离谱的错误,我找不到原因发生在哪里,但是知道代理服务器出错了,代理了后端给的接口,但是,却向本地发起请求,快把我整崩溃了 GET http://localhost:8080/xx/xx 404 (Not Found) 和Uncaught (in promise) Error: failed 开启代理后,发起请求,因为后端给的路径没有

    2024年02月07日
    浏览(53)
  • 解决Vue报错:Uncaught (in promise) NavigationDuplicated: Avoided redundant navigation to current location...

    解决方案: 方案一:只需在 router 文件夹下,添加如下代码: 方案二、使用 catch 方法捕获 router.push 异常。 方案三、在跳转时,判断是否跳转路由和当前路由是否一致,避免重复跳转产生问题。 index路由文件 菜单组件 修改后的截图

    2024年02月17日
    浏览(58)
  • Uncaught (in promise) error问题排查

    报错信息:Uncaught (in promise) error 其实前端已经拿到后端返回的数据了。 vue代码: JavaScript代码: 后台Java代码: ConutValue对象很简单,就是从数据库中统计出4个数字。 问题剖析: 从字面意思上看,是“未被发现的错误”,我之前一直觉得既然前端已经拿到后端返回的数据了

    2024年02月12日
    浏览(46)
  • 【前端异常】JavaScript错误处理:分析 Uncaught(in promise) error

    在开发过程中,JavaScript的错误处理是一个老生常谈的话题。当应用程序发生未捕获的异常时,Uncaught(in promise) error是其中最常见的错误类型。这篇文章将从多个方面详细阐述这种错误类型的原因与解决方案。 Promise是一种用于异步编程的原生JavaScript对象。它提供了一种处理异

    2024年02月05日
    浏览(89)
  • 【Bug排查】Uncaught (in promise) Error: Infinite redirect in navigation guard

    记一次Bug排查 今日在做尚硅谷的商品甄选项目时,遇到无法登录的问题:报错 Uncaught (in promise) Error: Infinite redirect in navigation guard 一开始我去搜CSDN,都说是路由的问题,我对前端也不了解,试着改了一下,发现没有用。我怀疑是前端包的问题,于是我重新下载解压了若干次资

    2024年02月07日
    浏览(53)
  • 解决:Uncaught (in promise) Error: Request failed with status code 400

    问题: 在写项目的时候,获取三级联动的数据,一直报以下错误 定位问题: 这个错误信息可能与在前端调用接口时存在问题有关。 400 (Bad Request) 错误可能是由于请求参数不正确或者缺少必要参数导致的。 具体指向: 这个错误信息中指定了一个URL,即 http://localhost:9528/dev-

    2024年02月08日
    浏览(39)
  • 解决 Uncaught (in promise) TypeError: list is not iterable 报错

    最近在项目中遇到 Uncaught (in promise) TypeError: list is not iterable 报错,虽然不影响代码运行,但是看着报错感觉有点难受,试试能不能解决它 看了很多篇文章,都是说使用 Object.keys() 可以解决问题 就先使用 Object.keys() 看看,代码运行之后 因为 Object.keys() 传入的是 null 和 undefin

    2024年02月11日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包