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

yudada-form

v0.1.12

Published

Dynamic form component for Vue 3 + Element Plus

Readme

yudada-form

基于 Vue 3 + Element Plus 的配置驱动动态表单组件,通过 config JSON 自动渲染表单字段、生成校验规则,并把字段变化事件透传给父组件(可用于“无查询按钮也能自动刷新数据”的交互)。

特性一览

  • 支持 configArray(普通表单)或 Object(分组表单)
  • 支持多类型表单控件(输入、选择、日期时间、开关、滑块、评分、穿梭框等)
  • 支持自动校验:required 自动生成校验规则;支持 rulescustomRules 叠加
  • 支持动态显示/隐藏:visibleshow(formData, item) 函数
  • 支持字段联动:
    • 父组件监听 field-change / field-input
    • 或在字段配置中使用 onChange / onInput
  • 支持 slotsuffixSlot:在控件内部渲染自定义内容、以及在表单项后缀渲染自定义内容
  • 支持表单方法透出:validate / validateField / resetFields / clearValidate
  • 支持扩展/覆盖内置组件映射:customComponentMap

安装

pnpm add yudada-form
pnpm add element-plus

使用

全局注册(推荐)

import { createApp } from "vue";
import ElementPlus from "element-plus";
import YudadaForm from "yudada-form";
import "element-plus/dist/index.css";

import App from "./App.vue";

const app = createApp(App);
app.use(ElementPlus);
app.use(YudadaForm);
app.mount("#app");

模板中直接使用:

<yudada-form :config="formConfig" v-model="formData" />

0.1.2 起,组件样式会随 JS 自动注入;一般不需要再手动 import "yudada-form/style.css"

局部引入

import { YudadaForm } from "yudada-form";
<template>
  <YudadaForm v-model="formData" :config="formConfig" />
</template>

组件 Props

组件的 props 主要用于控制表单整体样式、状态与分组行为:

  • config: Array | Object(必填),表单字段配置;Array 为普通表单,Object 为分组表单
  • modelValue: Object(可用 v-model),表单数据对象
  • labelWidth: string,label 宽度
  • labelPosition: "left" | "right" | "top",label 位置(默认 right
  • inline: boolean,是否内联布局
  • size: "" | "medium" | "small" | "mini",Element Plus 尺寸
  • disabled: boolean,禁用整个表单;单字段也可通过字段 disabled 进一步控制
  • showSectionTitle: boolean,分组表单是否显示 section 标题(默认 true
  • validateOnRuleChange: boolean,校验规则变更时是否重新触发校验(默认 true
  • sectionClass: string,给分组内容区域添加额外 class
  • defaultShowLabel: boolean,整张表单字段是否默认显示 label(默认 true
  • defaultShowColon: boolean,整张表单字段是否默认显示 label 后的冒号(默认 true
  • customComponentMap: Object,扩展/覆盖 type -> component 映射(用于自定义组件类型)

最简单用法(JSON 生成表单)

<template>
  <yudada-form :config="formConfig" v-model="formData" />
</template>

<script setup lang="ts">
import { ref } from "vue";

const formData = ref({});
const formConfig = ref([
  { label: "用户名", type: "input", model: "username", required: true },
  { label: "密码", type: "password", model: "password", required: true },
  {
    label: "性别",
    type: "select",
    model: "gender",
    options: [
      { label: "男", value: "male" },
      { label: "女", value: "female" },
    ],
  },
]);
</script>

config 字段结构(核心)

config 的每个字段项至少需要:

  • label:展示文字
  • type:控件类型(决定用哪个 Element Plus 组件)
  • model:表单数据字段名(会读写 v-model 的对象属性)

普通表单 vs 分组表单

  1. 普通表单:configArray
  2. 分组表单:configObject,例如:
const formConfig = {
  baseInfo: [
    { label: "姓名", type: "input", model: "name", required: true },
  ],
  otherInfo: [
    { label: "备注", type: "textarea", model: "remark" },
  ],
};

分组表单下,内部校验 prop 会使用 ${sectionName}.${item.model}(例如 baseInfo.name),因此 validateField/clearValidate 若传入 prop,需要按这个规则使用。

字段项常用配置

字段项(item)支持常见字段属性如下(均为可选,按需使用):

  • required: boolean:是否必填(会自动生成 rules
  • rules: Array:Element Plus 表单校验规则(会直接参与校验)
  • customRules: Array:额外校验规则(会与自动生成/已有 rules 进行合并)
  • defaultValue: any:当 modelValue 中不存在该 model 时的默认值覆盖
  • disabled: boolean:字段禁用(会与组件级 disabled 共同生效)
  • placeholder: string:输入提示
  • labelWidth: string:覆盖该字段的 label 宽度
  • showLabel: boolean:仅控制当前字段是否显示 label(优先级高于组件 defaultShowLabel
  • showColon: boolean:仅控制当前字段是否显示 label 后冒号(优先级高于组件 defaultShowColon
  • className: string:覆盖该字段 class
  • fullWidth: boolean:追加 full-width
  • formItemProps: Object:透传给 el-form-item
  • visible: boolean:控制该字段是否渲染(false 则不渲染)
  • show: (formData, item) => boolean:根据其他字段值动态决定是否渲染
  • onChange: (value, formData, item) => void:控件 change 触发时回调(可做字段联动)
  • onInput: (value, formData, item) => void:控件 input 触发时回调(可做字段联动)
  • slot: string:指定要渲染的具名 slot 名称(在控件内部)
  • suffixSlot: string:指定要渲染的后缀具名 slot 名称(在 el-form-item 后缀位置)

options / valueKey / labelKey

对于 selectselect-multipleradiocheckbox-groupcascader 等:

  • options: Array:选项列表
  • valueKey: string:当 option 为对象时,用哪个字段作为 value(默认 value
  • labelKey: string:当 option 为对象时,用哪个字段作为 label(默认 label
  • option 上可带 disabled: boolean:用于禁用单个选项

自动校验规则与触发器

组件内部在初始化 config 后,会为每个字段生成 formRules

  1. required: true 且未显式提供 rules,组件会自动生成一条规则:
    • required: true
    • message: "${label}不能为空"
    • trigger 根据字段 type 自动映射(输入类默认 blur,选择类/开关类/滑块/评分/穿梭框默认 change
  2. 若提供了 customRules: Array,则会把它们追加到当前规则数组中
  3. 若提供了 rules: Array,则会直接使用(并且仍可能被 customRules 追加)

触发器映射(来自组件内部 getTriggerType):

  • input / textarea / number / input-number / passwordblur
  • select / select-multiple / cascader / date* / time* / radio / checkbox-group / switch / slider / rate / color / transferchange

表单校验方法

父组件可通过 ref 调用(组件内部直接转发到 el-form):

  • validate(callback):整体校验
  • validateField(props, callback):单字段校验
  • resetFields():重置所有字段并清除校验状态
  • clearValidate(props):清除指定字段校验状态

示例:

<script setup lang="ts">
import { ref } from "vue";

const formRef = ref();

const submit = () => {
  formRef.value?.validate((valid: boolean) => {
    if (!valid) return;
    // 在此提交 formData
  });
};
</script>

<template>
  <yudada-form ref="formRef" :config="formConfig" v-model="formData" />
  <el-button type="primary" @click="submit">提交</el-button>
</template>

字段联动与“自动查询”(无查询按钮也能刷新)

组件会对每次字段变化触发事件:

  • field-change:当控件触发 change 时触发
  • field-input:当控件触发 input 时触发

事件签名:

  • field-change(fieldModel, value, item)
  • field-input(fieldModel, value, item)

父组件监听事件并查询(推荐)

<yudada-form
  v-model="formData"
  :config="formConfig"
  @field-change="handleFieldChanged"
  @field-input="handleFieldChanged"
/>
const handleFieldChanged = (fieldModel: string, value: any) => {
  // 这里做 debounce 更稳妥,避免输入框频繁请求
  queryData({ ...formData.value });
};

注意:组件内部还会在 formData 变化时持续 emit change,因此如果你只想要“字段变化后立即查询”,监听 field-change/field-input 通常更精确。

config 内部直接做联动(onChange / onInput)

你也可以在字段配置里实现联动。onChange/onInput 会收到当前 formData 引用:

{
  label: "类型",
  type: "select",
  model: "type",
  options: [
    { label: "默认", value: "default" },
    { label: "其他", value: "other" },
  ],
  onChange: (value, formData) => {
    // 直接改同一个 formData 对象,其他字段会自动跟着更新显示
    formData.remark = value === "other" ? "" : "不需要备注";
  },
}

动态显示/隐藏(show / visible)

{
  label: "备注",
  type: "textarea",
  model: "remark",
  show: (formData) => formData.type === "other",
}

或者:

{
  label: "备注",
  type: "textarea",
  model: "remark",
  visible: false,
}

Label / 冒号显示控制(全局 + 单项覆盖)

组件支持两层控制方式:

  1. 组件级默认值(作用于整张表单)
    • defaultShowLabel:默认是否显示 label(默认 true
    • defaultShowColon:默认是否显示冒号(默认 true
  2. 字段级覆盖(作用于单个字段)
    • showLabel
    • showColon

优先级规则:字段级配置 > 组件级默认值

示例:整表默认不显示,单字段开启

<template>
  <yudada-form
    v-model="formData"
    :config="formConfig"
    :default-show-label="false"
    :default-show-colon="false"
    label-width="100px"
  />
</template>

<script setup lang="ts">
import { ref } from "vue";

const formData = ref({});

const formConfig = ref([
  {
    label: "流程编号",
    type: "input",
    model: "flowNo",
    // 覆盖全局:当前字段显示 label 和冒号
    showLabel: true,
    showColon: true,
  },
  {
    label: "任务类型",
    type: "select",
    model: "taskType",
    options: [],
    // 跟随全局:不显示 label/冒号
  },
  {
    label: "申请人",
    type: "select",
    model: "applicant",
    options: [],
    // 仅显示 label,不显示冒号
    showLabel: true,
    showColon: false,
  },
]);
</script>

说明:当字段最终不显示 label(showLabel=false)且未单独设置 labelWidth 时,组件会自动把该字段 label-width 设为 0px,避免左侧空白占位。

分组表单标题

config 为对象且启用 showSectionTitle=true 时,组件会渲染每个 section 的标题。

组件内置了一个标题映射:

  • baseInfo -> 基本信息
  • otherInfo -> 其他信息
  • contractInfo -> 合同信息
  • detailInfo -> 详细信息

其余 sectionName 会原样显示。

你也可以通过 sectionClass 控制表单分组区域的 class。

事件列表(emits)

组件 emits 如下:

  • update:modelValueformData 变化时同步更新父组件的 v-model
  • changeformData 变化时触发(等价于“表单整体变化”)
  • field-change:字段 change 触发(更适合选择/开关类联动)
  • field-input:字段 input 触发(更适合输入框联动)

slots:slot 与 suffixSlot

字段项支持两个槽位配置:

  • slot: string:在“具体控件内部”渲染具名 slot
  • suffixSlot: string:在 el-form-itemsuffix 位置渲染具名 slot

示例(在组件内部插入内容):

{
  label: "用户名",
  type: "input",
  model: "username",
  slot: "usernamePrefix",
}

父组件:

<yudada-form :config="formConfig" v-model="formData">
  <template #usernamePrefix="{ item, value }">
    <span style="margin-right: 8px;">当前:{{ value }}</span>
  </template>
</yudada-form>

suffixSlot 示例同理,只是 slot 会挂在 el-form-itemsuffix

{ label: "年龄", type: "input-number", model: "age", suffixSlot: "ageSuffix" }

控件类型映射(type -> 组件)

组件内置映射(未匹配到时默认用 el-input):

  • input / number / passwordel-input
  • textareael-input
  • input-numberel-input-number
  • select / select-multipleel-select
  • cascaderel-cascader
  • time-pickerel-time-picker
  • time-selectel-time-select
  • date / date-select / datetime / datetime-picker / year-select / month / week / daterange / datetimerange / monthrangeel-date-picker
  • radioel-radio-group
  • checkbox-groupel-checkbox-group
  • switchel-switch
  • sliderel-slider
  • rateel-rate
  • colorel-color-picker
  • transferel-transfer

扩展/覆盖内置组件:customComponentMap

当你业务里有自定义组件类型(例如你项目原来用 gj-* 组件)时,可以通过 customComponentMap 扩展 type -> component 映射。

const customComponentMap = {
  "map-select": MyMapSelect,
};
<yudada-form
  :config="formConfig"
  v-model="formData"
  :custom-component-map="customComponentMap"
/>

默认值行为

modelValue 初始对象中不包含某字段的 model 时,组件会在初始化时补默认值:

  • select-multiple[]
  • checkbox-group[]
  • switchfalse
  • rate0
  • slider0
  • 其他:""

若字段项提供了 defaultValue,则优先使用 defaultValue

构建与发布(仓库侧)

pnpm i
pnpm build

发布到 npm(或私服):

npm login
npm publish