Skip to content

HardcoreInput 硬核输入框 ​

输入框校验器的终极形态。通过 Web Audio API 动态合成 8-bit 复古电子音效(零音频依赖),同时在校验结果变化时触发 Neobrutalist 表情弹跳与物理震动。

预览 ​

Preview

基础用法(Blur 校验)

多规则校验(Input 实时校验)

禁用音效

关闭抖动 (shakeOnError=false)

只读状态 (readonly)

安装 ​

pnpm dlx brutx-vue@latest add hardcore-input

用法 ​

vue
<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 合成三种音效:

音效波形说明
typeTriangle打字音效,带 50ms 节流
successSine校验通过,频率上升
failSquare校验失败,频率下降

可通过 sound prop 禁用音效。

视觉反馈 ​

  • 成功:输入框边框变为 --brutal-success 色,右侧显示酷表情 SVG
  • 错误:输入框边框变为 --brutal-destructive 色,右侧显示怒气表情 SVG,输入框产生抖动动画
  • 默认:无额外反馈

Form 集成 ​

HardcoreInput 可与 Form 系统集成,当存在于 FormField 中时自动同步校验状态:

vue
<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 系统或需要轻量内联校验的场景。

ts
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 ​

属性类型默认值说明
rulesMaybeRefOrGetter<ValidationRule<TValue>[]>[]校验规则数组;为空时 validate 永远返回 true 并将状态置为 default
validateOnMaybeRefOrGetter<'input' | 'blur' | 'submit'>'submit'校验触发时机(仅影响 shouldValidateOnInput / shouldValidateOnBlur 的判定,需调用方自行在对应事件中调用 validate)
defaultErrorMessageMaybeRefOrGetter<string>'Invalid value'规则返回 false 时的默认错误消息
onValidationChange(state: ValidationState, message?: string) => void—校验状态变化时回调(仅在状态实际变化时触发,避免重复)

返回值 ​

属性类型说明
validationStateRef<'default' | 'success' | 'error'>当前校验状态(响应式)
errorMessageRef<string>当前错误消息(响应式,无错误时为空字符串)
validate(value)(value: TValue) => boolean对给定值执行校验;通过返回 true,失败返回 false 并写入 errorMessage
reset()() => void重置为 default 状态并清空错误消息
shouldValidateOnInput()() => boolean是否配置为在 input 时机校验
shouldValidateOnBlur()() => boolean是否配置为在 blur 时机校验

ValidationRule ​

ts
type ValidationRule<TValue> = (value: TValue) => boolean | string

规则函数接收当前值,返回 true 表示通过,返回 string 表示失败并以该字符串作为错误消息,返回 false 表示失败并使用 defaultErrorMessage。

使用示例 ​

在自定义输入控件中复用同一套校验逻辑:

vue
<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 参考 ​

HardcoreInput — 属性
名称类型默认值说明
modelValue
string | undefined
undefined
当前输入字符串,可通过 v-model 受控绑定。
详情

声明类型

string | undefined

默认值详情

解析值
undefined

来源

HardcoreInput.vue:12

packages/ui/src/components/hardcore-input/HardcoreInput.vue

sound
boolean | undefined
true
启用或关闭输入音效及校验状态切换时的成功/失败音效。
详情

声明类型

boolean | undefined

字面量

  • false
  • true

默认值详情

解析值
true

来源

HardcoreInput.vue:13

packages/ui/src/components/hardcore-input/HardcoreInput.vue

rules
((val: string) => string | boolean)[] | undefined
[]

按实例调用工厂函数

按顺序执行的字符串校验函数;返回 true 表示通过,返回字符串表示失败及错误文案,返回 false 使用本地化通用错误文案。空数组不产生校验错误。
详情

声明类型

((val: string) => string | boolean)[] | undefined

默认值详情

解析值
[]

来源

HardcoreInput.vue:14

packages/ui/src/components/hardcore-input/HardcoreInput.vue

shakeOnError
boolean | undefined
true
校验失败时启用输入框抖动反馈。
详情

声明类型

boolean | undefined

字面量

  • false
  • true

默认值详情

解析值
true

来源

HardcoreInput.vue:15

packages/ui/src/components/hardcore-input/HardcoreInput.vue

type
string | undefined
"text"
传给原生 input 元素的 HTML 输入类型。
详情

声明类型

string | undefined

默认值详情

解析值
"text"

来源

HardcoreInput.vue:16

packages/ui/src/components/hardcore-input/HardcoreInput.vue

placeholder
string | undefined
undefined
输入框为空时显示的原生 placeholder 文本。
详情

声明类型

string | undefined

默认值详情

解析值
undefined

来源

HardcoreInput.vue:17

packages/ui/src/components/hardcore-input/HardcoreInput.vue

disabled
boolean | undefined
false
设置原生输入框为禁用状态。
详情

声明类型

boolean | undefined

字面量

  • false
  • true

默认值详情

解析值
false

来源

HardcoreInput.vue:18

packages/ui/src/components/hardcore-input/HardcoreInput.vue

readonly
boolean | undefined
false
设置原生输入框为只读状态。
详情

声明类型

boolean | undefined

字面量

  • false
  • true

默认值详情

解析值
false

来源

HardcoreInput.vue:19

packages/ui/src/components/hardcore-input/HardcoreInput.vue

validateOn
"input" | "submit" | "blur" | undefined
"blur"
选择组件自动触发校验的时机;submit 不会监听表单提交,需通过公开 validate() 主动调用。
详情

声明类型

"input" | "submit" | "blur" | undefined

字面量

  • "blur"
  • "input"
  • "submit"

默认值详情

解析值
"blur"

来源

HardcoreInput.vue:20

packages/ui/src/components/hardcore-input/HardcoreInput.vue

class
string | undefined
undefined
追加到输入框及校验提示外层容器的自定义 CSS 类。
详情

声明类型

string | undefined

默认值详情

解析值
undefined

来源

HardcoreInput.vue:21

packages/ui/src/components/hardcore-input/HardcoreInput.vue

HardcoreInput — 事件
名称签名或类型说明
@update:modelValue
[value: string]
用户输入或 IME 组合完成时发出输入字符串;IME 组合过程中的中间值不会发出。
详情

声明类型

[value: string]

来源

HardcoreInput.vue

packages/ui/src/components/hardcore-input/HardcoreInput.vue

@validation-change
[state: "default" | "success" | "error", message?: string | undefined]
校验状态改变或错误状态下错误文案改变时发出;重复的相同状态和文案不会重复通知。rules 为空时复位到 default 也会通知。
  • 规则返回 false 时,message 使用 hardcoreInput.invalidInput 文案“输入内容无效”。
详情

声明类型

[state: "default" | "success" | "error", message?: string | undefined]

字面量

  • "default"
  • "error"
  • "success"

来源

HardcoreInput.vue

packages/ui/src/components/hardcore-input/HardcoreInput.vue

HardcoreInput — 插槽
名称签名或类型说明
#default
{}
替换输入框右侧的默认校验表情区域;插槽不接收参数。
详情

声明类型

{}

来源

HardcoreInput.vue

packages/ui/src/components/hardcore-input/HardcoreInput.vue

HardcoreInput — 暴露成员
名称签名或类型说明
validate
() => boolean
使用当前 modelValue 主动校验,返回是否通过;若位于 Form 上下文中,会先同步表单值。
详情

声明类型

() => boolean

来源

HardcoreInput.vue:222

packages/ui/src/components/hardcore-input/HardcoreInput.vue

validationState
ValidationState
组件实例上暴露的校验状态;Vue 会自动解包内部 Ref,可通过 hardcoreInputRef.value.validationState 读取 default、success 或 error。
详情

声明类型

ValidationState

字面量

  • "default"
  • "error"
  • "success"

关联类型

ValidationState
类型定义 — ValidationState
export type ValidationState = 'default' | 'success' | 'error'

来源

HardcoreInput.vue:223

packages/ui/src/components/hardcore-input/HardcoreInput.vue

errorMessage
string
组件实例上暴露的当前校验错误文案;Vue 会自动解包内部 Ref,无错误时为空字符串。
详情

声明类型

string

来源

HardcoreInput.vue:224

packages/ui/src/components/hardcore-input/HardcoreInput.vue

可访问性 ​

  • 输入框设置了 :aria-invalid 和 :aria-describedby
  • 错误消息设置了 aria-live="polite"
  • 当用户偏好 prefers-reduced-motion: reduce 时,抖动和弹跳动画被禁用

蛮力铸就。