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

相关推荐
林焱_RPAAI12 小时前
影刀RPA技术深度:CSS选择器高级实战指南——伪类属性选择器与性能对比完全解析
vue.js·react.js
陳陈陳13 小时前
🚀 前端流式输出革命:SSE + BFF 架构从零到一实战指南
vue.js·架构·node.js
黄泉路醉s18 小时前
在Vant+Vue+TypeScript的H移动前端使用UnoCSS
前端·vue.js·typescript
我要两颗404西柚20 小时前
Stage three:VUE工程化与实战工具
前端·javascript·vue.js
看昭奚恤哭1 天前
基于 RuoYi-Vue-Pro 定制了一个后台管理系统 magic-admin , 开源出来!
前端·vue.js·开源
妙码生花2 天前
从 PHP 到 AI + Golang,程序员自救转型手记(四十五):前端远程下拉输入组件
前端·javascript·vue.js
Listen·Rain2 天前
AGENTS.md — Vue 3 Frontend Development
前端·javascript·vue.js
南风知我意啊2 天前
Vue3图片缩放拖拽组件全攻略
前端·javascript·vue.js
万亿少女的梦1682 天前
基于Spring Boot、Vue.js与MySQL的流浪猫狗救助系统设计与实现
vue.js·spring boot·mysql·javaweb·权限管理
早睡早起身体好1232 天前
Vue 3 路由与懒加载入门:从零完成一个迷你学习中心
javascript·vue.js·学习