更新记录

1.0.0(2025-10-31) 下载此版本

Features

  • 初始版本发布
  • 支持 8 种字段类型(input、textarea、number、picker、switch、date、radio、checkbox)
  • 日期选择使用 uni-app 原生 picker,无需额外依赖
  • 内置 4 种常用验证规则(required、email、phone、number)
  • 支持对象验证规则(min、max、pattern、validator)
  • 支持自定义验证函数
  • 支持动态表单
  • 支持 v-model 双向绑定(已优化避免无限循环)
  • 支持全局和单个字段禁用
  • 提供 validate、reset、clearValidate 方法
  • 完整的演示示例
  • 详细的使用文档
  • 完全独立,无任何外部组件依赖
  • 统一设计规范:使用主色 #1e80ff,圆角 12rpx,内边距 24rpx

平台兼容性

uni-app(3.6.12)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
√ √ √ √ √ √ √ √ √
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
√ √ √ √ √ √ √ √ √ - √ √

neo-form-schema

JSON Schema 驱动的动态表单组件,通过简单的配置快速生成表单,自动处理验证和状态管理。

特性

  • 配置驱动:通过 JSON Schema 配置快速生成表单
  • 多种字段类型:input、textarea、number、picker、switch、date、radio、checkbox
  • 内置验证:支持 required、email、phone、number 等常用验证规则
  • 自定义验证:支持自定义验证函数
  • 动态表单:支持根据条件动态显示/隐藏字段
  • 双向绑定:支持 v-model
  • 简单易用:最少配置原则,开箱即用
  • 全平台支持:H5、小程序、App

兼容性

Vue2 Vue3 H5 App 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅ ✅

安装

在 HBuilderX 中右键 uni_modules 目录,选择 从插件市场导入,搜索 neo-form-schema 安装。

或者直接复制 neo-form-schema 目录到项目的 uni_modules 目录下。

无任何依赖:此组件完全独立,无需安装其他组件。

快速开始

基础用法

<template>
  <view>
    <neo-form-schema
      v-model="formData"
      :schema="schema"
    />
    <button @click="handleSubmit">提交</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      formData: {},
      schema: [
        {
          type: 'input',
          field: 'username',
          label: '用户名',
          placeholder: '请输入用户名',
          rules: ['required']
        },
        {
          type: 'input',
          field: 'password',
          label: '密码',
          placeholder: '请输入密码',
          inputType: 'password',
          rules: ['required']
        }
      ]
    }
  },
  methods: {
    handleSubmit() {
      console.log('表单数据:', this.formData)
    }
  }
}
</script>

带验证的表单

<template>
  <view>
    <neo-form-schema
      ref="formRef"
      v-model="formData"
      :schema="schema"
    />
    <button @click="handleSubmit">提交</button>
  </view>
</template>

<script>
export default {
  data() {
    return {
      formData: {},
      schema: [
        {
          type: 'input',
          field: 'email',
          label: '邮箱',
          placeholder: '请输入邮箱',
          rules: ['required', 'email']
        },
        {
          type: 'input',
          field: 'phone',
          label: '手机号',
          placeholder: '请输入手机号',
          inputType: 'number',
          rules: ['required', 'phone']
        }
      ]
    }
  },
  methods: {
    handleSubmit() {
      // 验证表单
      if (this.$refs.formRef.validate()) {
        console.log('验证通过:', this.formData)
      } else {
        console.log('验证失败')
      }
    }
  }
}
</script>

完整的注册表单

<template>
  <neo-form-schema
    ref="formRef"
    v-model="formData"
    :schema="schema"
  />
</template>

<script>
export default {
  data() {
    return {
      formData: {},
      schema: [
        {
          type: 'input',
          field: 'username',
          label: '用户名',
          placeholder: '请输入用户名',
          rules: ['required', { min: 3, max: 20 }],
          tip: '3-20个字符'
        },
        {
          type: 'input',
          field: 'email',
          label: '邮箱',
          placeholder: '请输入邮箱',
          rules: ['required', 'email']
        },
        {
          type: 'picker',
          field: 'gender',
          label: '性别',
          placeholder: '请选择性别',
          options: ['男', '女', '保密'],
          rules: ['required']
        },
        {
          type: 'date',
          field: 'birthday',
          label: '生日',
          placeholder: '请选择生日'
        },
        {
          type: 'switch',
          field: 'agree',
          label: '同意用户协议'
        }
      ]
    }
  }
}
</script>

API

Props

参数 类型 默认值 说明
modelValue / v-model Object {} 表单数据对象
schema Array [] 表单配置数组
disabled Boolean false 全局禁用

Schema 配置

每个 schema 项支持以下配置:

参数 类型 必填 说明
type String 是 字段类型,见下方支持的类型
field String 是 字段名,对应 formData 的 key
label String 否 标签文本
placeholder String 否 占位符
rules Array 否 验证规则数组
disabled Boolean 否 是否禁用此字段
tip String 否 提示信息
options Array 否 选项数组(picker、radio、checkbox 类型必填)
inputType String 否 input 类型的子类型(text、password、number 等)
maxlength Number 否 最大长度(textarea 类型)

支持的字段类型

类型 说明 配置示例
input 文本输入 { type: 'input', field: 'name', label: '姓名' }
textarea 多行文本 { type: 'textarea', field: 'intro', label: '简介' }
number 数字输入 { type: 'number', field: 'age', label: '年龄' }
picker 单选选择器 { type: 'picker', field: 'city', label: '城市', options: ['北京', '上海'] }
switch 开关 { type: 'switch', field: 'agree', label: '同意协议' }
date 日期选择(使用原生 picker) { type: 'date', field: 'birthday', label: '生日' }
radio 单选组 { type: 'radio', field: 'gender', label: '性别', options: ['男', '女'] }
checkbox 多选组 { type: 'checkbox', field: 'hobby', label: '爱好', options: ['运动', '音乐'] }

内置验证规则

规则 说明 使用方式
required 必填 rules: ['required']
email 邮箱格式 rules: ['email']
phone 手机号格式 rules: ['phone']
number 数字 rules: ['number']

对象验证规则

{
  field: 'username',
  label: '用户名',
  rules: [
    'required',
    { 
      min: 3, 
      max: 20, 
      message: '用户名长度在3-20个字符' 
    }
  ]
}

支持的对象规则:

  • { required: true, message: '错误提示' } - 必填
  • { min: 3, message: '错误提示' } - 最小长度
  • { max: 20, message: '错误提示' } - 最大长度
  • { pattern: '^[a-zA-Z]+$', message: '错误提示' } - 正则验证
  • { validator: (value, formData) => { ... }, message: '错误提示' } - 自定义验证函数

自定义验证

{
  field: 'confirmPassword',
  label: '确认密码',
  rules: [
    'required',
    {
      validator: (value, formData) => {
        if (value !== formData.password) {
          return '两次密码输入不一致'
        }
        return null // 返回 null 表示验证通过
      }
    }
  ]
}

Methods

通过 ref 调用组件方法:

方法名 参数 返回值 说明
validate - Boolean 验证整个表单,返回是否通过
reset - - 重置表单数据和验证状态
clearValidate - - 清空验证错误

Events

事件名 参数 说明
update:modelValue formData 表单数据变化时触发

动态表单

支持根据条件动态生成表单:

<template>
  <neo-form-schema
    v-model="formData"
    :schema="dynamicSchema"
  />
</template>

<script>
export default {
  data() {
    return {
      formData: {}
    }
  },
  computed: {
    dynamicSchema() {
      const baseSchema = [
        {
          type: 'radio',
          field: 'deliveryType',
          label: '配送方式',
          options: ['快递配送', '到店自提']
        }
      ]

      // 根据选择动态添加字段
      if (this.formData.deliveryType === '快递配送') {
        baseSchema.push({
          type: 'textarea',
          field: 'address',
          label: '收货地址',
          rules: ['required']
        })
      }

      return baseSchema
    }
  }
}
</script>

常见问题

1. 如何设置初始值?

直接在 v-model 绑定的数据对象中设置:

data() {
  return {
    formData: {
      username: '张三',
      gender: '男'
    }
  }
}

2. 如何禁用某个字段?

在 schema 配置中设置 disabled: true:

{
  type: 'input',
  field: 'username',
  label: '用户名',
  disabled: true
}

3. 如何自定义错误提示?

使用对象规则并指定 message:

{
  field: 'username',
  label: '用户名',
  rules: [
    { 
      required: true, 
      message: '请输入用户名' 
    }
  ]
}

4. 如何实现条件验证?

使用自定义验证函数,根据条件返回错误或 null:

{
  field: 'email',
  label: '邮箱',
  rules: [
    {
      validator: (value, formData) => {
        // 只有选择了接收通知才必填
        if (formData.receiveNotify && !value) {
          return '请输入邮箱'
        }
        return null
      }
    }
  ]
}

许可

MIT License

更新日志

见 changelog.md

隐私、权限声明

1. 本插件需要申请的系统权限列表:

无

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

无

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

许可协议

MIT协议