10 分钟构建 Vue 3 端到端类型安全的表单

概述

在前端开发中,表单是用户交互的核心,但同时也是最容易出错的部分。字段名拼写错误、字段类型不一致、数据验证缺失,都会导致运行时错误、难以维护的代码,甚至安全隐患。

随着应用变得复杂,需要一种方式:

  • 从定义到提交全链路保证字段类型的一致性
  • 能让 TS 类型系统真正参与到表单开发的每一层
  • 能减少手动维护冗余类型,提高开发效率和可维护性

在本文中,我们通过 vue3 实现一个类型安全的 Form

创建 vue3 项目

通过 pnpm 创建一个 vue3 的 repo

bash 复制代码
pnpm create vue@latest

如何构建表单

使用 @vee-validate/zod

bash 复制代码
pnpm install vee-validate @vee-validate/zod

小试牛刀

App.js 复制代码
<script setup>
import { useForm } from 'vee-validate';
import { toTypedSchema } from '@vee-validate/zod';
import { z } from 'zod';

const { handleSubmit, defineField, isSubmitting, errors, meta, setFieldError } = useForm({
  validationSchema: toTypedSchema(z.object({
    name: z.string(),
    age: z.number().min(1),
  })),
});

const [name, nameAttrs] = defineField('name');
const [age, ageAttrs] = defineField('age');

const onSubmit = handleSubmit(async (values) => {
  console.log('Submitting...');
  await new Promise(resolve => setTimeout(resolve, 2000));
  console.log('Done!', values);
});

</script>

<template>
  <form @submit="onSubmit">
    <div>
      <label for="name">Name:</label>
      <input v-model="name" v-bind="nameAttrs" @input="() => setFieldError('name', '')" />
      <span>{{ errors.name }}</span>
    </div>
    <div>
      <label for="age">Age:</label>
      <input v-model="age" v-bind="ageAttrs" type="number" @input="() => setFieldError('age', '')" />
      <span>{{ errors.age }}</span>
    </div>
    <button :disabled="isSubmitting">
      {{ isSubmitting ? 'Submitting...' : 'Submit' }}
    </button>
    <pre>{{ meta }}</pre>
  </form>
</template>
相关推荐
毕设十刻11 小时前
基于Vue的新生入学报道管理系统(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
期待のcode11 小时前
JWT令牌
前端·javascript·spring boot·安全
JZXStudio11 小时前
Swift 6 + MLX + SwiftUI:三位一体本地AI架构蓝图
前端·ios
神秘的猪头11 小时前
彻底搞懂 React 组件通信:从 TodoList 实战出发,解锁 React 开发的“核心姿势” 🚀
前端·react.js·架构
若梦plus11 小时前
实现WebView JSBridge
前端
JS_GGbond11 小时前
揭秘微信扫码登录:那个小绿框背后的魔法
前端
C_心欲无痕11 小时前
vue3 - 响应式数ref与reactive的深度解析
前端·javascript·vue.js
全栈老石11 小时前
TypeScript 中 Type 和 Interface 傻傻分不清?看完这篇就不纠结了
前端·typescript
沈千秋.11 小时前
xss.pwnfunction.com闯关(1~6)
java·前端·xss