一个灵活、可链式调用的 TypeScript/JavaScript 校验规则工厂。
- 链式 API,可构建复杂校验规则
- 支持 string、number、array、boolean、object、symbol、bigint、null、undefined
- 可自定义错误信息
- 易于扩展与集成
- 支持 TypeScript
pnpm add ruler-factory
# 或
npm install ruler-factory
# 或
yarn add ruler-factory<script setup lang="ts">
import { ref } from 'vue'
import { rulerFactory } from 'ruler-factory'
const r = rulerFactory((validator) => {
return (value) => {
const e = validator(value)
return e ? e.message : true
}
})
const model = ref({
name: '',
email: '',
})
</script>
<template>
<var-form>
<var-input v-model="model.name" placeholder="姓名" :rules="r().required('必填').min(2, '长度不正确').done()" />
<var-input v-model="model.age" placeholder="邮箱" :rules="r().email('必须是邮箱格式').done()" />
</var-form>
</template><script setup lang="ts">
import { ref } from 'vue'
import { rulerFactory } from 'ruler-factory'
import type { FieldRule } from 'vant'
const r = rulerFactory<FieldRule>((validator, params) => ({
validator(value) {
const e = validator(value)
return e ? e.message : true
},
trigger: ['onChange', 'onBlur', 'onSubmit'],
...params,
}))
const model = ref({
name: '',
email: '',
})
</script>
<template>
<van-form>
<van-cell-group inset>
<van-field v-model="model.name" label="姓名" placeholder="姓名" :rules="r().required('必填').done()" />
<van-field v-model="model.email" label="邮箱" placeholder="邮箱" :rules="r().email('必须是邮箱格式').done()" />
</van-cell-group>
</van-form>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { FormItemRule } from 'naive-ui'
import { rulerFactory } from 'ruler-factory'
const r = rulerFactory<FormItemRule>((validator, params = {}) => ({
trigger: ['blur', 'change', 'input'],
validator: (_, value) => validator(value),
...params,
}))
const model = ref({
name: '',
age: 20,
})
</script>
<template>
<n-form :model>
<n-form-item path="name" label="姓名" :rule="r().required('必填').min(2, '长度不正确').done()">
<n-input v-model:value="model.name" />
</n-form-item>
<n-form-item path="age" label="年龄" :rule="r().number().required('必填').negative('必须为负数').done()">
<n-input-number v-model:value="model.age" />
</n-form-item>
</n-form>
</template><script setup lang="ts">
import { ref } from 'vue'
import type { FormItemRule } from 'element-plus'
import { rulerFactory } from 'ruler-factory'
const r = rulerFactory<FormItemRule>((validator, params) => ({
validator(_, value, callback) {
const e = validator(value)
e ? callback(e) : callback()
},
trigger: ['blur', 'change', 'input'],
...params,
}))
const model = ref({
name: '',
email: '',
})
</script>
<template>
<el-form :model>
<el-form-item prop="name" label="姓名" :rules="r().required('必填').done()">
<el-input v-model="model.name" />
</el-form-item>
<el-form-item prop="email" label="邮箱" :rules="r().email('必须是邮箱格式').done()">
<el-input v-model="model.email" />
</el-form-item>
</el-form>
</template>以 Naive UI 为例
import { FormItemRule } from 'naive-ui'
import { RulerContext, rulerFactory, RulerFactoryMessage } from 'ruler-factory'
interface RulerExtendedContext {
ip(message: RulerFactoryMessage, params?: FormItemRule): RulerContext<FormItemRule, FormItemRule, this>
}
const r = rulerFactory<FormItemRule, FormItemRule, RulerExtendedContext>(
(validator, params = {}) => ({
trigger: ['blur', 'change', 'input'],
validator: (_, value) => validator(value),
...params,
}),
(ctx) => {
function ip(message: RulerFactoryMessage, params?: FormItemRule) {
ctx.addRule((value) => {
// 自行实现 isString 和 isIP
if (!isString(value) || !isIP(value)) {
return new Error(ctx.getMessage(message))
}
}, params)
return ctx
}
return { ip }
},
)
r().ip('IP 格式错误').done().string(message?, params?).number(message?, params?).array(message?, params?).boolean(message?, params?).object(message?, params?).symbol(message?, params?).bigint(message?, params?).null(message?, params?).undefined(message?, params?).true(message?, params?).false(message?, params?)
.required(message)
.min(value, message, params?).max(value, message, params?).length(value, message, params?).regex(regexp, message, params?).startsWith(value, message, params?).endsWith(value, message, params?).includes(value, message, params?).uppercase(message, params?).lowercase(message, params?).email(message, params?)
.number().min(value, message, params?).number().max(value, message, params?).number().gt(value, message, params?).number().gte(value, message, params?)别名 .min.number().lt(value, message, params?).number().lte(value, message, params?)别名 .max.number().positive(value, message, params?).number().negative(value, message, params?)
.bigint().min(value, message, params?).bigint().max(value, message, params?).bigint().gt(value, message, params?).bigint().gte(value, message, params?)别名 .min.bigint().lt(value, message, params?).bigint().lte(value, message, params?)别名 .max.bigint().positive(value, message, params?).bigint().negative(value, message, params?)
.array().min(value, message, params?).array().max(value, message, params?).array().length(value, message, params?).array().includes(value, message, params?)
.is(fn, message, params?).not(fn, message, params?)
.done()
.addRule(validator)
.trim().toLowerCase().toUpperCase().transform(fn)
MIT