nuxt3-路由验证

在 nuxt3中,希望做路由验证,可以借助 definePageMeta 实现

场景

现在有2个页面,A 页面和B页面, 从A页面跳转到B页面携带了参数,如果参数不符合要求,就不要跳转到B页面, 要求做一个 拦截

基础环境

json 复制代码
"nuxt": "^3.11.2", 
"vue": "^3.4.27", 
"node": "v20.12.2"

代码

a页面代码

html 复制代码
<template>
  <div>
    第一个页面,传参过去到b

    <button @click="toPage">跳转</button>
  </div>
</template>

<script setup>

const router = useRouter()

const toPage = () => {
  router.push({
    path: '/validate-route/b',
    query: {
      // 正常要传递一个数字,现在传递一个非数字
      age: 'as'
    }
  })
  .catch(err => {
    console.log('捕获到的错误信息');
    console.log(err);
  })
}
</script>

b页面代码

html 复制代码
<template>
  <div>
    <div>B页面</div>
  </div>
</template>

<script setup>
definePageMeta({
  validate: async (route) => {
    if (!route.query.age) {
      throw createError({ statusCode: 401, message: '没有传递age参数'})
    }

    let isNumber = /^\d+$/.test(route.query.age);

    if (!isNumber) {
      console.log('age不是数字');
      // throw createError({ statusCode: 401, message: '参数验证不通过'})
      // throw createError({ message: '参数验证不通过'})
      return Promise.reject('是的,返回了一个Promise.reject 告诉你参数不通过')
    } else {
      // 正常情况
      return true;
    }
  },
});
</script>

效果

页面仍旧是在 A页面, B页面也正确拦截到了, 错误消息我们也可以自行捕获并处理

官网文档

路由验证的官网文档,写的很隐晦, 翻译软件 翻译的中文意思是,"你可以返回一个xxx对象" 并没有对这个对象做限定

这里的对象,不是 普通对象,应该是Error 对象

我是根据TS 类型,才明白这里应该如何返回

  1. 我们去具体看看TS 类型定义,从ts 类型注释中可以看到,是这样定义的
typescript 复制代码
validate?: (route: RouteLocationNormalized) => boolean | Partial<NuxtError> | Promise<boolean | Partial<NuxtError>>;
  1. 继续查看,NuxtError 是怎么定义类型的, 继承了 H3Error 这个对象
typescript 复制代码
export interface NuxtError<DataT = unknown> extends H3Error<DataT> {
}
  1. 再继续看H3Error 类型
typescript 复制代码
declare class H3Error<DataT = unknown> extends Error {
    static __h3_error__: boolean;
    statusCode: number;
    fatal: boolean;
    unhandled: boolean;
    statusMessage?: string;
    data?: DataT;
    cause?: unknown;
    constructor(message: string, opts?: {
        cause?: unknown;
    });
    toJSON(): Pick<H3Error<DataT>, "data" | "statusCode" | "statusMessage" | "message">;
}

H3Error 又继承了 Error 对象, 所以,如果 validate 不返回一个 boolean类型, 就得返回一个 NuxtError 对象 或者一个 Promise<NuxtError>

小结

所以,上面的validate 可以返回如下的值

Promise<Boolean>

js 复制代码
validate: () => {
    if (不符合条件) {
        return Promise.reject(false)
        // 或者
        return Promise.reject('是的,返回了一个Promise.reject 告诉你参数不通过')
    }
}

boolean

js 复制代码
validate: (route) => {
    if (不符合条件)  return false
    
    return true
}

NuxtError

js 复制代码
// 要携带这些信息
throw createError({ statusCode: 401, message: '参数验证不通过'})

// 没有状态码也是可以的
throw createError({ message: '随便写的参数'})

其他

为什么在A页面的router 的 catch 能捕获到错误?

vue-router的知识, 路由是异步的

scss 复制代码
router.push()

router.replace()

返回的都是一个 Promise<.....>

相关推荐
徐小夕44 分钟前
下载量超 30 万的开源智能体 Prime Agent:它把自己从 TypeScript 重写成了 Rust
前端·vue.js·github
toooooop81 小时前
CRMEB 故障排查笔记:安全网关只放行 GET/POST 怎么办
前端·javascript·vue.js·thinkphp6·crmeb
软件技术NINI2 小时前
基于SpringBoot和Vue的项目评审系统
javascript·vue.js·spring boot·后端·spring·毕业设计·毕设
FRing0314 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
Java小卷14 小时前
JuanForm vs FormCreate!Vue3 表单引擎联动配置 PK!
vue.js·低代码
小郎君6581 天前
Vue 多标签页的加载态设计:为什么我没有用 Suspense 实现 PageLoading
vue.js·算法
yilaisai1 天前
前端开发遇到的一些细节问题整理
vue.js
华玥作者1 天前
Vue 3 + TypeScript + uni-app 组件库推荐:hy-app(华玥组件库)
vue.js·typescript·uni-app
阿琳a_1 天前
b-map-viewer:面向 Vue 3 的地图可视化 SDK,从接入到展示再到交互分析
前端·javascript·vue.js·gis·数据可视化·地图
齐 飞1 天前
VUE2常用语法总结
javascript·vue.js