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<.....>

相关推荐
小白CAD39 分钟前
前端vue打印后端对象为[object,object]
前端·javascript·vue.js
程序员云翼6 小时前
7-理财平台
java·vue.js·spring boot·后端·毕设
不熬夜的臭宝6 小时前
每天10个vue面试题(一)
前端·vue.js·面试
朝阳397 小时前
vue3【实战】来回拖拽放置图片
javascript·vue.js
不如喫茶去7 小时前
VUE自定义新增、复制、删除dom元素
前端·javascript·vue.js
长而不宰7 小时前
vue3+electron项目搭建,遇到的坑
前端·vue.js·electron
阿垚啊7 小时前
vue事件参数
前端·javascript·vue.js
加仑小铁7 小时前
【区分vue2和vue3下的element UI Dialog 对话框组件,分别详细介绍属性,事件,方法如何使用,并举例】
javascript·vue.js·ui
Python私教8 小时前
zdppy+onlyoffice+vue3解决文档加载和文档强制保存时弹出警告的问题
vue.js·python
过去式的美好8 小时前
vue前端通过sessionStorage缓存字典
前端·vue.js·缓存