HardcoreInput 硬核输入框
输入框校验器的终极形态。通过 Web Audio API 动态合成 8-bit 复古电子音效(零音频依赖),同时在校验结果变化时触发 Neobrutalist 表情弹跳与物理震动。
预览
基础用法(Blur 校验)
多规则校验(Input 实时校验)
禁用音效
关闭抖动 (shakeOnError=false)
只读状态 (readonly)
安装
pnpm dlx brutx-vue@latest add hardcore-input用法
<script setup>
import { ref } from 'vue'
import { HardcoreInput } from 'brutx-ui-vue'
const value = ref('')
const minLength = (val) => val.length >= 5 || '至少需要 5 个字符'
const hasNumber = (val) => /\d/.test(val) || '必须包含数字'
</script>
<template>
<HardcoreInput
v-model="value"
placeholder="输入内容..."
:rules="[minLength, hasNumber]"
validate-on="blur"
/>
</template>校验触发时机
| 模式 | 说明 |
|---|---|
blur | 失焦时校验(默认) |
input | 每次输入时实时校验 |
submit | 外部调用 validate() 时校验 |
音效系统
通过 useAudioEngine composable 使用 Web Audio API 合成三种音效:
| 音效 | 波形 | 说明 |
|---|---|---|
type | Triangle | 打字音效,带 50ms 节流 |
success | Sine | 校验通过,频率上升 |
fail | Square | 校验失败,频率下降 |
可通过 sound prop 禁用音效。
视觉反馈
- 成功:输入框边框变为
--brutal-success色,右侧显示酷表情 SVG - 错误:输入框边框变为
--brutal-destructive色,右侧显示怒气表情 SVG,输入框产生抖动动画 - 默认:无额外反馈
Form 集成
HardcoreInput 可与 Form 系统集成,当存在于 FormField 中时自动同步校验状态:
<Form v-slot="{ handleSubmit }">
<FormField v-slot="{ componentField }" name="username">
<FormItem>
<FormLabel>用户名</FormLabel>
<HardcoreInput v-bind="componentField" :rules="[minLength]" />
<FormMessage />
</FormItem>
</FormField>
</Form>组合式函数
useFormFieldValidation
HardcoreInput 内部的校验状态机已抽取为独立的 useFormFieldValidation 组合式函数,可在任何自定义表单控件中复用同一套校验逻辑(规则求值、状态机切换、错误消息管理、触发时机控制)。它不依赖 vee-validate,适合无法接入 Form 系统或需要轻量内联校验的场景。
import { useFormFieldValidation } from 'brutx-ui-vue'
import type { UseFormFieldValidationOptions, ValidationRule, ValidateOn } from 'brutx-ui-vue'
// 校验规则:返回 true 表示通过,返回字符串表示错误消息
const minLength: ValidationRule<string> = (val) => val.length >= 5 || '至少需要 5 个字符'
const hasNumber: ValidationRule<string> = (val) => /\d/.test(val) || '必须包含数字'
const {
validationState, // 当前校验状态
errorMessage, // 当前错误消息
validate, // 主动校验
reset, // 重置为默认状态
shouldValidateOnInput, // 是否在 input 时机校验
shouldValidateOnBlur, // 是否在 blur 时机校验
} = useFormFieldValidation({
rules: [minLength, hasNumber],
validateOn: 'blur',
defaultErrorMessage: '校验失败',
onValidationChange: (state, message) => {
// 状态变化回调,可用于联动音效、震动等副作用
},
})UseFormFieldValidationOptions
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
rules | MaybeRefOrGetter<ValidationRule<TValue>[]> | [] | 校验规则数组;为空时 validate 永远返回 true 并将状态置为 default |
validateOn | MaybeRefOrGetter<'input' | 'blur' | 'submit'> | 'submit' | 校验触发时机(仅影响 shouldValidateOnInput / shouldValidateOnBlur 的判定,需调用方自行在对应事件中调用 validate) |
defaultErrorMessage | MaybeRefOrGetter<string> | 'Invalid value' | 规则返回 false 时的默认错误消息 |
onValidationChange | (state: ValidationState, message?: string) => void | — | 校验状态变化时回调(仅在状态实际变化时触发,避免重复) |
返回值
| 属性 | 类型 | 说明 |
|---|---|---|
validationState | Ref<'default' | 'success' | 'error'> | 当前校验状态(响应式) |
errorMessage | Ref<string> | 当前错误消息(响应式,无错误时为空字符串) |
validate(value) | (value: TValue) => boolean | 对给定值执行校验;通过返回 true,失败返回 false 并写入 errorMessage |
reset() | () => void | 重置为 default 状态并清空错误消息 |
shouldValidateOnInput() | () => boolean | 是否配置为在 input 时机校验 |
shouldValidateOnBlur() | () => boolean | 是否配置为在 blur 时机校验 |
ValidationRule
type ValidationRule<TValue> = (value: TValue) => boolean | string规则函数接收当前值,返回 true 表示通过,返回 string 表示失败并以该字符串作为错误消息,返回 false 表示失败并使用 defaultErrorMessage。
使用示例
在自定义输入控件中复用同一套校验逻辑:
<script setup lang="ts">
import { ref } from 'vue'
import { useFormFieldValidation } from 'brutx-ui-vue'
const value = ref('')
const { validationState, errorMessage, validate, shouldValidateOnBlur } = useFormFieldValidation({
rules: [(v) => v.length >= 3 || '至少 3 个字符'],
validateOn: 'blur',
})
function onBlur() {
if (shouldValidateOnBlur()) validate(value.value)
}
</script>
<template>
<input
v-model="value"
@blur="onBlur"
:aria-invalid="validationState === 'error'"
:class="{
'border-brutal-success': validationState === 'success',
'border-brutal-destructive': validationState === 'error',
}"
/>
<p v-if="errorMessage" class="text-brutal-destructive text-sm">{{ errorMessage }}</p>
</template>提示:
useFormFieldValidation不绑定具体控件,所有时机判断(shouldValidateOnInput/shouldValidateOnBlur)只返回布尔值,由调用方决定在哪个事件中调用validate。submit时机需调用方在外部(如表单提交时)显式调用validate。
程序化控制
通过组件 ref 可主动调用校验并读取当前校验状态与错误文案;成员类型和行为见 API 参考。
API 参考
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
modelValue | string | undefined | undefined | 当前输入字符串,可通过 v-model 受控绑定。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | |||
sound | boolean | undefined | true | 启用或关闭输入音效及校验状态切换时的成功/失败音效。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | |||
rules | ((val: string) => string | boolean)[] | undefined | []按实例调用工厂函数 | 按顺序执行的字符串校验函数;返回 true 表示通过,返回字符串表示失败及错误文案,返回 false 使用本地化通用错误文案。空数组不产生校验错误。 |
详情声明类型((val: string) => string | boolean)[] | undefined 默认值详情
来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | |||
shakeOnError | boolean | undefined | true | 校验失败时启用输入框抖动反馈。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | |||
type | string | undefined | "text" | 传给原生 input 元素的 HTML 输入类型。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | |||
placeholder | string | undefined | undefined | 输入框为空时显示的原生 placeholder 文本。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | |||
disabled | boolean | undefined | false | 设置原生输入框为禁用状态。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | |||
readonly | boolean | undefined | false | 设置原生输入框为只读状态。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | |||
validateOn | "input" | "submit" | "blur" | undefined | "blur" | 选择组件自动触发校验的时机;submit 不会监听表单提交,需通过公开 validate() 主动调用。 |
详情声明类型"input" | "submit" | "blur" | undefined 字面量
默认值详情
来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | |||
class | string | undefined | undefined | 追加到输入框及校验提示外层容器的自定义 CSS 类。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | |||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
@update:modelValue | [value: string] | 用户输入或 IME 组合完成时发出输入字符串;IME 组合过程中的中间值不会发出。 |
详情声明类型[value: string] 来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | ||
@validation-change | [state: "default" | "success" | "error", message?: string | undefined] | 校验状态改变或错误状态下错误文案改变时发出;重复的相同状态和文案不会重复通知。rules 为空时复位到 default 也会通知。
|
详情声明类型[state: "default" | "success" | "error", message?: string | undefined] 字面量
来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | ||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
#default | {} | 替换输入框右侧的默认校验表情区域;插槽不接收参数。 |
详情声明类型{}来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | ||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
validate | () => boolean | 使用当前 modelValue 主动校验,返回是否通过;若位于 Form 上下文中,会先同步表单值。 |
详情声明类型() => boolean 来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | ||
validationState | ValidationState | 组件实例上暴露的校验状态;Vue 会自动解包内部 Ref,可通过 hardcoreInputRef.value.validationState 读取 default、success 或 error。 |
详情声明类型ValidationState 字面量
关联类型 ValidationState 类型定义 — ValidationStateexport type ValidationState = 'default' | 'success' | 'error' 来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | ||
errorMessage | string | 组件实例上暴露的当前校验错误文案;Vue 会自动解包内部 Ref,无错误时为空字符串。 |
详情声明类型string 来源packages/ui/src/components/hardcore-input/HardcoreInput.vue | ||
可访问性
- 输入框设置了
:aria-invalid和:aria-describedby - 错误消息设置了
aria-live="polite" - 当用户偏好
prefers-reduced-motion: reduce时,抖动和弹跳动画被禁用