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

相关推荐
wycode35 分钟前
Vue2实践(2)之用component做一个动态表单(一)
前端·javascript·vue.js
第七种黄昏37 分钟前
Vue3 中的 ref、模板引用和 defineExpose 详解
前端·javascript·vue.js
pepedd8642 小时前
还在开发vue2老项目吗?本文带你梳理vue版本区别
前端·vue.js·trae
前端缘梦2 小时前
深入理解 Vue 中的虚拟 DOM:原理与实战价值
前端·vue.js·面试
HWL56792 小时前
pnpm(Performant npm)的安装
前端·vue.js·npm·node.js
柯南95273 小时前
Vue 3 reactive.ts 源码理解
vue.js
柯南95273 小时前
Vue 3 Ref 源码解析
vue.js
小高0073 小时前
面试官:npm run build 到底干了什么?从 package.json 到 dist 的 7 步拆解
前端·javascript·vue.js
JayceM4 小时前
Vue中v-show与v-if的区别
前端·javascript·vue.js
HWL56794 小时前
“preinstall“: “npx only-allow pnpm“
运维·服务器·前端·javascript·vue.js