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

相关推荐
ze_juejin17 分钟前
Vue3 + Vite + Ant Design Vue + Axios + Pinia 脚手架搭建
前端·vue.js
小样还想跑2 小时前
axios无感刷新token
前端·javascript·vue.js
用户3802258598242 小时前
vue3源码解析:响应式机制
前端·vue.js
时间会给答案scidag2 小时前
报错 400 和405解决方案
vue.js·spring boot
白杨木影子被拉长2 小时前
多状态映射不同样式(scss语法)
vue.js·uni-app
长路 ㅤ   3 小时前
前端技术博客汇总文档
javascript·vue.js·css3·html5·前端技术
Jinxiansen02114 小时前
unplugin-vue-components 最佳实践手册
前端·javascript·vue.js
婉婉耶5 小时前
VUE带你乘风破浪~
前端·vue.js
乌兰麦朵5 小时前
Vue吹的颅内高潮,全靠选择性失明和 .value 的PUA!
前端·vue.js
Goodbaibaibai5 小时前
创建一个简洁的Vue3 + TypeScript + Vite + Pinia + Vue Router项目
javascript·vue.js·typescript