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

报错图示:

Error: Invalid navigation guard
Uncaught (in promise) Error: Invalid navigation guard
在这里插入图片描述

错误影响描述:

配置开发、测试、生产时候,因为是公众号,所以想在开发环境下免鉴权,不走微信获取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.envapp.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/#/Homeconst toPath = VITE_HOST + '/#' + to.path// 核心步骤,获取codeconst 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";// 从地址栏获取codeconst 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获取openIdconst res = await getWechatInfoByCode({ code })if (res && res.code == 0) {store.setOpenid(res.data.openid)isBindAccount()} else {showToast(res?.info || '请求失败!');}} else {  //获取codewindow.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.envapp.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/#/Homeconst toPath = VITE_HOST + '/#' + to.path// 核心步骤,获取codeconst 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";// 从地址栏获取codeconst 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获取openIdconst res = await getWechatInfoByCode({ code })if (res && res.code == 0) {store.setOpenid(res.data.openid)isBindAccount()} else {showToast(res?.info || '请求失败!');}} else {  //获取codewindow.location.replace(hrefurl)}}} else {next()}
})
// 路由守卫 end
备注:

vue3的ref变量使用必须加.value,卧槽,反人类啊,开倒车!!!经常忘记,导致我疯狂debug

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/4861.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

potplayer放大画面,画面拖拽。备份

放大画面: 按住alt和鼠标左键,就可以拖动放大后的画面了 窗口化示图

【DC-DC】APS54083 降压恒流驱动器大功率深度调光 舞台 RGB 汽车照明 台灯驱动芯片

产品描述 APS54083 是一款 PWM 工作模式,高效率、外围简单、外置功率 MOS 管,适用于 5-220V 输入高精度降压 LED 恒流驱动芯片。输出最大功率150W最大电流 6A。APS54083 可实现线性调光和 PWM 调光,线性调光脚有效电压范围 0.5-2.5V.PWM 调光频率范围 1…

学习babylon.js --- [3] 开启https

babylonjs提供WebVR功能,但是使用这个功能得用https,本文讲述如何使用自签名证书来开启https,基于第二篇文章中搭建的工程。 一 生成自签名证书 首先要安装openssl,这个去网上搜下就行了。安装完之后在终端下输入openssl回车可以…

MongoDB

MongoDB概述 MongoDB是一个基于分布式文件存储的数据库。由C语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。 MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。 它支持的数据结构非…

状态模式:游戏、工作流引擎中常用的状态机是如何实现的?

从今天起,我们开始学习状态模式。在实际的软件开发中,状态模式并不是很常用,但是在能够用到的场景里,它可以发挥很大的作用。从这一点上来看,它有点像我们之前讲到的组合模式。 可以简短的回顾一下组合模式&#xff1a…

uniapp安卓签名证书生成,签名证书的SHA1,SHA256,MD5获取

uniapp安卓证书生成有两种方式,一种是去dcloud开发者中心生成证书,另一种是安装jre环境,自己生成证书 第一种 dcloud生成证书 去该项目对应的应用处,生成证书需要等几分钟,生成后可以查看证书信息 第二种 自己生成…

如何下载SRA存放在AWS的原始数据

通常,我们都是利用prefetch从NCBI上获取数据,然后用fasterp-dump/fastq-dump 转成fastq。但遗憾的SRA的数据是原数据的有损压缩,比如说我19年参与发表的文章里单细胞数据上传的是3个文件,但是当时的faster-dump/fastq-dump只能拆出…

【ArcGIS Pro二次开发】(46):要素类从上到下、从左到右排序

要素类经过编辑之后,【OBJECTID】字段会变得不规律。应部分网友要求,做了这个从上到下、从左到右排序的工具。 不过后来在ArcGIS Pro中发现了一个【排序】工具,已经可以完美实现这个功能需求,发现自己做了个白工。 不过做了不能白…

Ghost Buster Pro for mac(快速清理卸载的应用残存文件)

Ghost Buster Pro for mac可从您已卸载的应用程序中查找并删除文件。该应用程序速度快如闪电,可立即释放内存。 许多应用程序都安装在计算机上,但它们通常只会在您的计算机上停留很短的时间。每个应用程序都会创建文件,但删除应用程序不会删…

若依字典使用

若依字典使用 此文章使用的若依是大于3.7.0版本的 JS文件配置 main.js中引入全局变量和方法 import DictData from /components/DictData DictData.install()DictData.js配置 可以从DictData.js中看出在install方法中调用了字典查询接口,在install方法中可以做…

前端 | (五)CSS三大特性及常用属性 | 尚硅谷前端html+css零基础教程2023最新

学习来源:尚硅谷前端htmlcss零基础教程,2023最新前端开发html5css3视频 文章目录 📚CSS三大属性🐇层叠性🐇继承性🐇优先级 📚CSS常用属性🐇像素的概念🐇颜色的表示⭐️表…

火狐安卓版支持油猴了!后面将支持更多扩展插件

日前火狐浏览器每夜构建版的安卓版已经带来了更多扩展程序支持,这其中就包括大名鼎鼎的油猴扩展程序。本次火狐浏览器每夜构建版更新新增五款扩展程序支持,并且按照谋智基金会说法还会支持更多的扩展程序。 下载地址:https://ftp.mozilla.org…

WEB:FlatScience

背景知识 sql注入 SQLite数据库知识 SQLite3注入方法 题目 用dirsearch进行扫描,下面几个关键目录:robots.txt,login.php,admin.php,剩下的目录就是一些pdf格式的论文了 一个一个访问并查看源代码,在查看l…

windows下安装consul、springboot整合consul

Spring Cloud Consul通过自动配置和绑定到Spring Environment和其他Spring编程模型习语,为Spring Boot应用程序提供Consul集成。通过一些简单的注解,可以快速启用和配置应用程序内的常用模式,并使用Hashicorp的Consul构建大型分布式系统。提供…

检测到错误页面web应用服务器版本信息泄露

详细描述 Web服务器未能正确处理异常请求导致Web服务器版本信息泄露,攻击者收集到服务器信息后可进行进一步针对性攻击。 解决办法 临时修复建议如下: 1、关闭web服务器错误提示。 2、关闭运行平台的错误提示。 3、建立错误机制,不要把真实…

MySQL八股学习总览-from 小林coding

MySQL八股学习总览-from 小林coding MySql执行流程连接MySQL服务器查询缓存解析SQL执行SQL预处理器优化器执行器 MySql执行流程 连接MySQL服务器 经过如下的命令,就可以与MySQL服务器建立起连接,三次握手 mysql -h$ip -u$user -p服务端查询多少个客户端连接 show processlis…

干货分享:商城系统开发方式

商城系统是一种为了满足电子商务需求而开发的系统,它能够实现在线购物、支付、订单管理等功能。在当今互联网时代,商城系统的开发方式多种多样。那么,商城系统开发方式有哪些呢? 1、完全独立自主开发 完全独立自主开发是指企业根…

【C++】仿函数(less)

C中的仿函数 class Solution { public:struct cmp{bool operator()(const pair<string,int>&kv1,const pair<string,int>&kv2){if(kv1.second<kv2.second) return true;if(kv1.secondkv2.second&&kv1.first>kv2.first) return true;return …

TCP/IP详解

目录 一、OSI参考模型 1.图示 2.OSI七层模型各自作用 3.七层通信过程 二、IP协议 1.IPv4首部 2.IPv6首部 三、TCP协议 1.tcp首部格式 2.握手挥手图示 3.握手流程 4.为什么要三次握手&#xff1f; 5.四次挥手流程 6.为什么要四次分手&#xff1f; 7.为什么要等待…