TypeScript前端數(shù)據(jù)校驗(yàn)c快速上手指南
一、Zod 是什么?
Zod 是一個(gè)TypeScript 優(yōu)先的類型校驗(yàn)庫,核心作用是:
- 用簡(jiǎn)潔的語法定義「數(shù)據(jù)校驗(yàn)規(guī)則 + TypeScript 類型」(一份代碼,雙重收益);
- 校驗(yàn)前端表單、API 響應(yīng)、環(huán)境變量等任意數(shù)據(jù),返回清晰的錯(cuò)誤信息;
- 零依賴、體積小,適配前端 / Node.js 項(xiàng)目,是替代 Joi、Yup 的主流選擇。
二、5 分鐘快速上手(Vue3/Vite 項(xiàng)目為例)
步驟 1:安裝
npm install zod # 或 yarn/pnpm pnpm add zod
步驟 2:核心用法(定義 → 校驗(yàn) → 提取類型)
Zod 的核心邏輯是:先定義 Schema 校驗(yàn)規(guī)則 → 用 Schema 校驗(yàn)數(shù)據(jù) → 自動(dòng)推導(dǎo) TS 類型。
// src/utils/validate.ts
import { z } from 'zod';
// 1. 定義校驗(yàn)規(guī)則(Schema)
const UserSchema = z.object({
// 必選字符串,非空
username: z.string().min(2, '用戶名至少2個(gè)字符').max(20),
// 可選數(shù)字,大于0
age: z.number().optional().positive('年齡必須為正數(shù)'),
// 郵箱格式校驗(yàn)
email: z.string().email('請(qǐng)輸入正確的郵箱格式'),
// 枚舉值限制
role: z.enum(['admin', 'user', 'guest'], '角色只能是admin/user/guest'),
// 嵌套對(duì)象
address: z.object({
city: z.string(),
street: z.string().optional()
})
});
// 2. 提取 TS 類型(無需手動(dòng)寫 interface)
type User = z.infer<typeof UserSchema>;
// 3. 校驗(yàn)數(shù)據(jù)
function validateUser(data: unknown) {
try {
// 嚴(yán)格校驗(yàn):不符合規(guī)則會(huì)拋錯(cuò)
const validData = UserSchema.parse(data);
console.log('校驗(yàn)通過', validData);
return { success: true, data: validData };
} catch (error) {
// 捕獲錯(cuò)誤并格式化
if (error instanceof z.ZodError) {
const errMsg = error.errors.map(item => ({
field: item.path.join('.'), // 錯(cuò)誤字段(如 address.city)
message: item.message // 錯(cuò)誤提示
}));
return { success: false, errors: errMsg };
}
return { success: false, errors: [{ field: 'unknown', message: '未知錯(cuò)誤' }] };
}
}
// 測(cè)試:校驗(yàn)合法數(shù)據(jù)
const validUser = {
username: '張三',
email: 'zhangsan@test.com',
role: 'user',
address: { city: '北京' }
};
console.log(validateUser(validUser)); // success: true
// 測(cè)試:校驗(yàn)非法數(shù)據(jù)
const invalidUser = {
username: '張', // 長(zhǎng)度不足
email: '123', // 郵箱格式錯(cuò)誤
role: 'super', // 枚舉值錯(cuò)誤
address: { city: 123 } // 類型錯(cuò)誤
};
console.log(validateUser(invalidUser));
// success: false,errors 包含所有錯(cuò)誤字段和提示
步驟 3:項(xiàng)目實(shí)戰(zhàn)場(chǎng)景
場(chǎng)景 1:校驗(yàn)前端表單(Vue3 示例)
<!-- src/components/LoginForm.vue -->
<template>
<form @submit.prevent="submitForm">
<input v-model="form.email" placeholder="郵箱" />
<div v-if="errors.email">{{ errors.email }}</div>
<input v-model="form.password" placeholder="密碼" />
<div v-if="errors.password">{{ errors.password }}</div>
<button type="submit">提交</button>
</form>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { z } from 'zod';
// 定義表單校驗(yàn)規(guī)則
const LoginSchema = z.object({
email: z.string().email('請(qǐng)輸入正確的郵箱'),
password: z.string().min(6, '密碼至少6位')
});
type LoginForm = z.infer<typeof LoginSchema>;
// 表單數(shù)據(jù)
const form = ref<LoginForm>({ email: '', password: '' });
const errors = ref<Record<string, string>>({});
// 提交表單
const submitForm = () => {
// 清空之前的錯(cuò)誤
errors.value = {};
// 校驗(yàn)數(shù)據(jù)(safeParse 不拋錯(cuò),返回結(jié)果)
const result = LoginSchema.safeParse(form.value);
if (!result.success) {
// 格式化錯(cuò)誤信息
result.error.errors.forEach(item => {
errors.value[item.path[0]] = item.message;
});
return;
}
// 校驗(yàn)通過,調(diào)用接口
console.log('表單數(shù)據(jù)合法', result.data);
};
</script>
場(chǎng)景 2:校驗(yàn) API 響應(yīng)
// src/api/user.ts
import { z } from 'zod';
import axios from 'axios';
// 定義 API 響應(yīng)規(guī)則
const UserListSchema = z.array(
z.object({
id: z.number(),
name: z.string(),
avatar: z.string().url().optional() // 可選URL
})
);
// 請(qǐng)求接口并校驗(yàn)響應(yīng)
async function getUserList() {
const res = await axios.get('/api/users');
// 校驗(yàn)響應(yīng)數(shù)據(jù),確保符合預(yù)期
const validData = UserListSchema.parse(res.data);
return validData;
}
場(chǎng)景 3:校驗(yàn)環(huán)境變量(Vite 項(xiàng)目)
// src/utils/env.ts
import { z } from 'zod';
// 定義環(huán)境變量規(guī)則
const EnvSchema = z.object({
VITE_API_BASE: z.string().url('API地址必須是合法URL'),
VITE_GA_ID: z.string().optional()
});
// 校驗(yàn) Vite 環(huán)境變量
const env = EnvSchema.parse(import.meta.env);
// 導(dǎo)出類型安全的環(huán)境變量
export default env;
三、高頻實(shí)用 API 速查
表格
| API 示例 | 作用 |
|---|---|
z.string().min(2) | 字符串,最小長(zhǎng)度 2 |
z.number().int() | 整數(shù) |
z.boolean() | 布爾值 |
z.array(z.string()) | 字符串?dāng)?shù)組 |
z.object({ a: z.string() }) | 對(duì)象校驗(yàn) |
z.enum(['a', 'b']) | 枚舉值限制 |
z.date() | 日期類型 |
z.any() | 任意類型 |
z.optional(z.string()) | 可選字符串 |
z.nullable(z.string()) | 可空字符串 |
schema.parse(data) | 嚴(yán)格校驗(yàn),失敗拋錯(cuò) |
schema.safeParse(data) | 安全校驗(yàn),返回結(jié)果(不拋錯(cuò)) |
z.infer<typeof schema> | 從 Schema 提取 TS 類型 |
總結(jié)
- Zod 核心是「Schema 定義 → 數(shù)據(jù)校驗(yàn) → 自動(dòng)推導(dǎo) TS 類型」,一份代碼兼顧校驗(yàn)和類型;
- 常用場(chǎng)景:表單校驗(yàn)、API 響應(yīng)校驗(yàn)、環(huán)境變量校驗(yàn),適配前端 / Node.js;
- 核心 API:
z.object/z.string/z.number定義規(guī)則,parse/safeParse校驗(yàn)數(shù)據(jù),z.infer提取類型。
上手關(guān)鍵:先定義 Schema,再用 safeParse 校驗(yàn)數(shù)據(jù)(避免拋錯(cuò)),最后格式化錯(cuò)誤信息返回給用戶。
到此這篇關(guān)于TypeScript前端數(shù)據(jù)校驗(yàn)c快速上手指南的文章就介紹到這了,更多相關(guān)前端數(shù)據(jù)校驗(yàn)Zod庫內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript如何將base64圖片轉(zhuǎn)化為URL格式
這篇文章主要給大家介紹了關(guān)于JavaScript如何將base64圖片轉(zhuǎn)化為URL格式的相關(guān)資料,Base64是一種編碼方式,而不是真正的加密方式,即使算Base64也僅用作一個(gè)簡(jiǎn)單的加密來保護(hù)某些數(shù)據(jù),而真正的加密通常都比較繁瑣,需要的朋友可以參考下2023-07-07
一文詳解Proxy和Object.defineProperty的使用與區(qū)別
在JavaScript中,對(duì)象是一種核心的數(shù)據(jù)結(jié)構(gòu),而對(duì)對(duì)象的操作也是開發(fā)中經(jīng)常遇到的任務(wù),本文將深入比較Proxy和Object.defineProperty,感興趣的小伙伴可以了解下2023-12-12
JavaScript編寫一個(gè)簡(jiǎn)易購物車功能
這篇文章主要為大家詳細(xì)介紹了JavaScript簡(jiǎn)易購物車功能的編寫代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
js中的preventDefault與stopPropagation詳解
本篇文章主要是對(duì)js中的preventDefault與stopPropagation進(jìn)行了介紹,需要的朋友可以過來參考下,希望對(duì)大家有所幫助2014-01-01

