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

vue-dc-form

v1.0.6

Published

XForm 是一个基于 Vue 3 的表单组件库,提供了表单的封装和动态组件渲染功能。

Readme

本demo插件的说明

XForm 表单组件

XForm 是一个基于 Vue 3 的表单组件库,提供了表单的封装和动态组件渲染功能。

特性

  • 支持 Element Plus 大部分表单组件
  • 基于配置驱动,简化表单开发
  • 内置表单验证功能
  • 支持自定义插槽
  • 提供表单 API 控制方法

目录结构

src/ 
├─ components/ 
│ └─ DcForm/ # 表单封装核心目录 
│    ├── index.ts # 导出文件 
│    └── src/ # 源代码目录 
│       ├── FormWrapper.vue # 表单容器(处理校验/数据绑定) 
│       ├── UploadWrapper.vue # 上传组件包装器 
│       ├── hooks.ts # 钩子函数(如useXFormApi) 
│       ├── types/ # 类型声明文件夹 
│       │ └── types.ts # 类型声明 
│       └── tools/ # 工具函数 
│         ├── componentRegistry.ts # 组件注册表 
│         ├── registerElementComponents.ts # 注册Element组件 
│         ├── elItem.ts # Element表单项目处理 
│         └── rule.ts # 表单验证规则

组件参数

组件参数

config数组配置项-必传-具体对象配置见 src-types-types.ts- FormItemConfig-可参考最后配置示例

initialValues表单数据对象-必传

footerShow 是否显示 提交 重置 按钮 -可选(默认不显示)

……其他原el的Form API - 可选-比如表单尺寸……

// FormItemConfig参数说明
/** 基础配置 */
interface BaseFormItemConfig {
  /** 组件绑定的属性名 */
  prop: string
  /** 组件的label */
  label?: string
  value?: any
  /** 占位符(eg:请输入 ) */
  placeholder?: string
  /** 组件的参数配置 */
  componentProps?: Record<string, any>
  // 校验规则集成 -el 是基于( async-validator ) 封装的校验规则
  rules?: Array<RuleItem>
  // 自定义插槽支持
  slotName?: string
  /** 自定义或者原el组件中的事件 */
  events?: Record<string, (...args: any[]) => void>
}

/** 表单项基础配置 */
export interface FormItemConfig extends BaseFormItemConfig {
  /** 为哪种类型(组件) */
  type: ComponentType
  /** 组件的子组件(用于扩展) 如:单选是el-radio-group和el-radio组合的 */
  children?: childrenConfig
  /** item的label宽度 */
  labelWidth?: string | number
  /**  是否在行内显示校验信息 */
  inlineMessage?: string | boolean
  /** 表单item的尺寸 */
  size?: '' | 'large' | 'default' | 'small'
  /** item的宽度 */
  width?: string | number
}

/** 子组件基础配置 */
export interface childrenConfig extends BaseFormItemConfig {
  /** 子组件类型 */
  type: childrenType
  /** 用于不用label展示的项 */
  htmlText?: string

  prop?: string
  data: childrenConfig[]
}

使用示例

<template>
  <XForm :config="formConfig" :initialValues="formData" @register="useFormApi.register" />
</template>

<script setup>
import { XForm, type FormItemConfig, useXFormApi } from 'vue-dc-form'

// 组件里面的方法useFormApi是ref对象
const useFormApi = useXFormApi();

const formConfig = ref<FormItemConfig[]>([
  {
    type: 'el-input',
    label: '用户名',
    prop: 'username',
    placeholder: '请输入用户名',
    rules: [{ required: true, message: '用户名不能为空' }]
  },
  {
    type: 'el-input',
    label: '密码',
    prop: 'password',
    componentProps: {
      type: 'password'
    },
    rules: [{ required: true, message: '密码不能为空' }]
  }
])

const formData = ref({
  username: '',
  password: ''
})
</script>

表单方法

// 提交表单
useFormApi.value
  .submit()
  .then((data) => {
    console.log('表单数据:', data)
  })
  .catch((err) => {
    console.error('表单验证失败:', err)
  })

// 重置表单
useFormApi.value.resetFields()

// 手动验证表单
useFormApi.value.validate()

支持的表单组件

XForm 支持以下 Element Plus 表单组件:

  • 输入框 (el-input)
  • 数字输入框 (el-input-number)
  • 选择器 (el-select)
  • 日期选择器 (el-date-picker)
  • 时间选择器 (el-time-picker)
  • 单选框 (el-radio-group)
  • 多选框 (el-checkbox-group)
  • 开关 (el-switch)
  • 滑块 (el-slider)
  • 评分 (el-rate)
  • 文件上传 (el-upload)
  • 穿梭框 (el-transfer)
  • 级联选择器 (el-cascader)
  • 颜色选择器 (el-color-picker)

自定义插槽

XForm 支持通过插槽自定义表单内容:

<XForm :config="formConfig">
  <template #test_slot="{ formData }">
    <el-button @click="handleCustomAction">自定义操作</el-button>
  </template>
</XForm>

维护

增加自定义事件

// 1.src/types/types.ts文件中
export interface XFormApiEvents {
  // ……………………
  // 在这先注册
}
// 2.src/FormWrapper.vue
const api: XFormApi = {
  // ………………
  // 添加自定义事件
}

配置示例

const formConfig = ref<FormItemConfig[]>([
  { type: 'slot', slotName: 'test_slot', prop: 'test_slot', label: '测试' },
  {
    type: 'el-input',
    label: '姓名',
    prop: 'name',
    placeholder: '请输入姓名',
    width: 12,
  },
  {
    type: 'el-input',
    label: '密码',
    prop: 'password',
    width: 12,
    componentProps: { type: 'password' },
    placeholder: '请输入姓名',
  },
  {
    type: 'el-radio-group', // 单选框组
    label: '性别',
    prop: 'gender',
    width: 24,
    componentProps: { 'text-color': '#af1967' },
    children: {
      type: 'el-radio',
      data: [
        { htmlText: '男', value: 'man', prop: 'male' },
        { htmlText: '女', value: 'girl', prop: 'male' },
      ],
    },
  },
  {
    label: '日期',
    prop: 'date',
    type: 'el-date-picker',
    width: 24,
    componentProps: {
      type: 'date',
      placeholder: '选择日期',
      valueFormat: 'YYYY-MM-DD',
    },
    rules: [{ required: true, message: '请选择日期', trigger: 'change' }],
  },
  {
    type: 'el-checkbox-group',
    label: '爱好',
    prop: 'hobby',
    width: 24,
    children: {
      type: 'el-checkbox',
      data: [
        { htmlText: '吃饭', value: 'eat', prop: 'eat' },
        { htmlText: '睡觉', value: 'sleep', prop: 'sleep' },
        { htmlText: '打豆豆', value: 'do', prop: 'do' },
      ],
    },
    events: {
      change: (val: any) => {
        console.log(val, '----val----')
      },
    },
  },
  {
    type: 'el-select',
    label: '选择角色:',
    prop: 'Roles',
    placeholder: '请选择角色',
    children: {
      type: 'el-option',
      data: [
        { label: '超级管理员', value: 'admin' },
        { label: '普通用户', value: 'user' },
        { label: '游客', value: 'visitor' },
      ],
    },
    componentProps: { multiple: true, collapseTags: true },
    events: {
      change: (val: any) => {
        formData.value.Roles = val
      },
    },
  },
  {
    type: 'el-cascader',
    label: '地址',
    prop: 'address',
    width: 24,
    placeholder: '请选择地址',
    events: {
      change: (val: any) => {
        console.log(val, '------****** val ******------')
      },
    },
    componentProps: {
      'popper-append-to-body': false,
      size: 'default',
      options: [
        {
          value: 'sc',
          label: '四川',
          children: [
            {
              value: 'cd',
              label: '成都',
              children: [
                { value: 'cdx', label: '成都高新区' },
                { value: 'cdy', label: '成都高新区' },
              ],
            },
          ],
        },
        {
          value: 'cq',
          label: '重庆',
          children: [
            { value: 'cqx', label: '渝北区' },
            { value: 'jb', label: '江北区' },
          ],
        },
      ],
      clearable: true, // 可清空
      props: {
        value: 'value', // 节点值的属性名
        label: 'label', // 节点标签的属性名
        children: 'children', // 子节点的属性名
      },
    },
  },
  { type: 'el-color-picker', label: '喜欢什么颜色?', prop: 'color', width: 24 },
  {
    type: 'el-date-picker',
    label: '年月日',
    prop: 'csnyr',
    width: 24,
    componentProps: {
      type: 'datetime',
      placeholder: '选择日期时间',
      valueFormat: 'YYYY-MM-DD',
    },
  },
  {
    type: 'el-input-number',
    label: '年龄',
    prop: 'age',
    width: 24,
    componentProps: {
      valueOnClear: 0, // 清空时的值
    },
  },
  { type: 'el-rate', label: '评分', prop: 'rate', width: 24 },
  { type: 'el-slider', label: '人身进度', prop: 'slider' },
  {
    type: 'el-switch',
    label: '开关',
    prop: 'switch',
    width: 24,
    componentProps: { activeText: '开', inactiveText: '关' },
  },
  {
    type: 'el-time-picker',
    label: '时间',
    prop: 'time',
    width: 24,
    componentProps: {
      valueFormat: 'HH:mm:ss', // 设置时间格式为 HH:mm:ss
    },
  },
  { type: 'el-time-select', label: '固定时间', prop: 'gdsj' },
  {
    type: 'el-upload',
    label: '上传图片',
    prop: 'file',
    componentProps: {
      limit: 2,
      'auto-upload': false,
      'list-type': 'picture-card',
    },
    events: {
      onExceed: (files: any) => {
        console.log(files, '------****** files ******------')
      },
    },
  },
])