npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@a-drowned-fish/vue-hookform

v1.0.10

Published

vue3 表单库

Readme

Vue Hook Form

一个基于 Vue 3 的表单处理库。

安装

npm install @a-drowned-fish/vue-hookform

依赖

  • Vue 3.x
  • Yup (表单验证库)

基本用法

<template>
    <form @submit.prevent="handleSubmit(onSubmit)">
        <div>
            <label>用户名</label>
            <input v-model="state.username" type="text" />
            <span v-if="errorState.username?.length">
                {{ errorState.username.join(", ") }}
            </span>
        </div>
        <div>
            <label>邮箱</label>
            <input v-model="state.email" type="email" />
            <span v-if="errorState.email?.length">
                {{ errorState.email.join(", ") }}
            </span>
        </div>
        <button type="submit">提交</button>
    </form>
</template>

<script setup lang="ts">
import { useForm } from "@a-drowned-fish/vue-hookform";
import * as yup from "yup";

const schema = yup.object({
    username: yup.string().required("用户名必填"),
    email: yup.string().email("邮箱格式不正确").required("邮箱必填"),
});

const { state, errorState, handleSubmit } = useForm({
    schema,
    defaultValues: {
        username: "",
        email: "",
    },
});

// 如果 验证不通过,不会执行 onSubmit 函数
// 如果 验证通过,会执行 onSubmit 函数,参数为 表单数据
const onSubmit = (data: typeof state) => {
    console.log("表单数据:", data);
};
</script>

API

useForm

返回值

| 属性 | 类型 | 说明 | | ------------- | ------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | | state | reactive<Record<string, any>> | 表单状态对象,用于双向绑定 | | errorState | reactive<Record<string, Array<string>>> | 错误信息对象 | | reset | () => void | 重置表单到默认值 | | handleSubmit | (onSubmit?: (data: Record<string, any>) => void) => Promise<void> | 处理表单提交和验证 | | disabled | boolean | 是否禁用提交按钮 (注: 由 入参函数 disabled 函数 决定,如果想要使用此返回值,则必须传入disabled函数) 默认值:false | | actionOnError | (errorState: Record<string, Array<string>>) => void | 验证失败时的回调函数,参数为 错误信息对象 |

示例

完整示例

<template>
    <div>
        <form @submit.prevent="handleSubmit(onSubmit)">
            <div>
                <label>用户名</label>
                <input v-model="state.username" type="text" />
                <div v-if="errorState.username?.length" class="error">
                    <span v-for="(err, index) in errorState.username" :key="index">{{ err }}</span>
                </div>
            </div>
            <div>
                <label>邮箱</label>
                <input v-model="state.email" type="email" />
                <div v-if="errorState.email?.length" class="error">
                    <span v-for="(err, index) in errorState.email" :key="index">{{ err }}</span>
                </div>
            </div>
            <div>
                <label>年龄</label>
                <input v-model.number="state.age" type="number" />
                <div v-if="errorState.age?.length" class="error">
                    <span v-for="(err, index) in errorState.age" :key="index">{{ err }}</span>
                </div>
            </div>
            <button type="submit">提交</button>
            <button type="button" @click="reset">重置</button>
        </form>
    </div>
</template>

<script setup lang="ts">
import { useForm } from "@a-drowned-fish/vue-hookform";
import * as yup from "yup";

const schema = yup.object({
    username: yup.string().required("用户名必填").min(3, "用户名至少3个字符"),
    email: yup.string().email("邮箱格式不正确").required("邮箱必填"),
    age: yup.number().typeError("年龄必须是数字").min(18, "必须年满18岁").max(100, "年龄不能超过100"),
});

const { state, errorState, reset, handleSubmit, disabled } = useForm({
    schema,
    defaultValues: {
        username: "",
        email: "",
        age: 0,
    },
    // 入参 disabled函数 作用, 在执行handleSubmit(onSubmit) 函数前,根据disabled函数返回值判断是否需要更新errorState 报错信息,如果返回true,则不更新errorState 报错信息
    disabled: (values) => {
        return values.username === "";
    },
});

const onSubmit = (data: typeof state) => {
    console.log("表单验证通过:", data);
    // 发送请求等操作
};
</script>

<style scoped>
.error {
    color: red;
    font-size: 12px;
}
</style>

注意事项

  1. schema 未提供时,handleSubmit 将直接调用 onSubmit 而不进行验证
  2. 错误信息以数组形式存储,支持一个字段多个错误提示
  3. defaultValues 的键需要与 schema 中定义的字段对应
  4. 使用 v-model.number 处理数字类型字段