坏了,用了装饰器之后,我的校验变成java的样子了

1,073 阅读3分钟

坏了,用了装饰器之后,我的校验变成java的样子了

1. 前言

最近在做表单校验时同事总说做校验的时候模型和校验分离了,导致同样的字段名需要写两次才行。

类似这样

const user = reactive({
    userName: '',
    password: ''
})

const userRules = userSchema({
    userName: yup.string().required()
})

这样使用感觉就比较麻烦,同样一个字段需要书写两遍。

于是我就想到可不可以使用类中的字段装饰器来做这个事情?

2. 装饰器校验

我想如果可以直接在定义对象的时候,通过注解的方式,把校验的信息定义到字段上。

那不就和后台 java 的校验方式一致了吗?

1738896413176.jpg

说干就干,我立马写了一个简单的注解校验库 @mtdst/v


<script>

import { required, useValid, min, max, V, len, pattern } from '@mtdst/v'

const { model, errors, validate, validateFields, clean} = useValid(class {
  @V('用户名/手机号', [required(), min(3), max(32)])
  userName = "";

  // 动态校验
  @V('密码', () => loginWay.value == 'password' ? [required(), pattern(RegExp('^(?=.*[0-9])(?=.*[a-zA-Z])[0-9a-zA-Z]'))] : [])
  password = "";
  
  // 或者也可以分开写
  @V.field('校验码')
  @V.required()
  @V.len(6)
  code = "";
})

async function sendCode() {
	clean()
	await validateFields(['userName'])
	// 发送校验码逻辑
}


async function login() {
	clean()
	await validate()
	// 登录逻辑
}

</script>

<template>
	<input v-model="model.userName" />
	<span>{{errors.userName}}</span>
	<input v-model="model.password" />
	<span>{{errors.password}}</span>
	<input v-model="model.code" />
	<span>{{errors.code}}</span>
	<button @click="sendCode">发送校验码</button>
	<button @click="login">登录</button> 
</template>

这样通过在字段上直接使用注解的方式就可以进行校验了

3. 如何使用

首先安装 @mtdst/v

 npm install @mtdst/v

1. useValid 函数

useValid 是核心函数,用于初始化表单校验逻辑。

参数说明
  • clazz:定义表单字段和校验规则的类。
  • isNeedWatch(可选,boolean):是否需要监听表单变化并自动校验,默认为 true

2.返回值

  • model:响应式的表单数据。
  • form:响应式的表单数据。
  • errors:响应式的错误信息集合。
  • validate:全量校验函数。
  • validateFields:特定字段校验函数。
  • reset:重置表单和错误信息。
  • clean:清空错误信息。

这里 modelform 是一个对象,只是方便不同命名习惯的人进行导入

这里有两种使用方式

// 第一种使用数组的方式放入导入的校验规则
@V('用户名/手机号', [required(), min(3), max(32)])
userName = "";

// 第二种分开写使用 V.xxx 的方式使用
@V.field('校验码')
@V.required()
@V.len(6)
code = "";

3.默认的校验

内置的默认的校验有

  • 必填校验

    @V.required('必填项提示')
    
  • 最小长度校验

    @V.min(3, '最小长度提示')
    
  • 最大长度校验

    @V.max(10, '最大长度提示')
    
  • 正则校验

    @V.pattern(/^[A-Za-z0-9]+$/, '正则提示')
    

后面这个提示语如果不写,则会是默认的提示信息

4. 自定义校验

@V.custom((name, key, value, model) => {
  // 自定义校验逻辑
  if (value !== 'custom') {
    return `${name} 必须是 custom`;
  }
  return null;
})

或者
@V('用户名/手机号', [(name, key, value, model) => {
  // 自定义校验逻辑
  if (value !== 'custom') {
    return `${name} 必须是 custom`;
  }
  return null;
}])

自定义校验 会传入 4 个参数

  • name:用户定义的 field 名称
  • key:表单的键名称
  • value:表单的键的值
  • model:表单实体化对象

如果需要异步校验,则将函数申明为 async 即可

结语

大概就是这样,源码地址在 github.com/2507483326/… 上。

时间有限,主要给各位大佬分享一个思路。