{"id":16265735,"url":"https://github.com/d-xuanmo/v-form","last_synced_at":"2025-05-06T20:42:49.567Z","repository":{"id":41689564,"uuid":"249326394","full_name":"D-xuanmo/v-form","owner":"D-xuanmo","description":"🎉 (Vue 2)基于 Vant-UI 进行二次封装动态生成表单，通过 JSON 的形式配置，内部集成繁琐的校验规则，可扩展的校验","archived":false,"fork":false,"pushed_at":"2023-08-19T13:33:11.000Z","size":2289,"stargazers_count":87,"open_issues_count":9,"forks_count":26,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-05-01T04:38:05.253Z","etag":null,"topics":["dynamic-form","form","vant-ui","vue","vue-form"],"latest_commit_sha":null,"homepage":"https://www.xuanmo.xin/-/v-form/","language":"Vue","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/D-xuanmo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-03-23T03:24:23.000Z","updated_at":"2025-03-21T14:45:33.000Z","dependencies_parsed_at":"2024-10-10T17:20:33.838Z","dependency_job_id":"1ba4b1e5-8f37-4235-8e64-d8d31333d9eb","html_url":"https://github.com/D-xuanmo/v-form","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/D-xuanmo%2Fv-form","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/D-xuanmo%2Fv-form/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/D-xuanmo%2Fv-form/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/D-xuanmo%2Fv-form/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/D-xuanmo","download_url":"https://codeload.github.com/D-xuanmo/v-form/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252768760,"owners_count":21801371,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dynamic-form","form","vant-ui","vue","vue-form"],"created_at":"2024-10-10T17:20:27.410Z","updated_at":"2025-05-06T20:42:49.509Z","avatar_url":"https://github.com/D-xuanmo.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 基于 Vant-UI 表单封装的动态表单组件\n\n\u003e Vue3 版动态表单 [https://github.com/D-xuanmo/dynamic-form](https://github.com/D-xuanmo/dynamic-form)\n\n* 目前已经集成的组件（Address/Checkbox/DatePicker/Input/Radio/Select/Text/Switch/Upload）\n* 组件不满足的情况可自定义开发组件或者使用 `slot` 的形式\n* 组件的调用方式采取 `JSON` 配置的形式，具体参数见model数据说明\n* 校验规则已经集成 `VeeValidate` 插件，也可以自定义扩展规则，更多资料 [https://logaretm.github.io/vee-validate](https://logaretm.github.io/vee-validate)\n* [在线演示，可编辑](https://codesandbox.io/s/v-formshili-3hs2c)\n\n## 语法约定\n* `Mixin` 公用方法使用 `__` 作为前缀\n* 事件传递使用 `e__` 作为前缀\n* `@` 为组件校验规则保留关键字\n\n## 本地运行本项目\n```base\n# 安装依赖\n$ npm run bootstarp\n\n# 启动项目\n$ npm run dev\n```\n\n## 安装\n```bash\n# 推荐使用 yarn 安装，使用 npm 可能会存在依赖不全的情况\nyarn add @xuanmo/v-form\n```\n\n## 使用\n\n### 引入注册组件\n```js\n// 引入组件\nimport VForm from '@xuanmo/v-form'\nimport '@xuanmo/v-form/packages/style/index.less'\n\n// 不经过编译引入方式，（不推荐）\n// import VForm from '@xuanmo/v-form/dist/v-form.umd.min.js'\n// import '@xuanmo/v-form/dist/index.css'\n\n// 覆盖变量引入此文件替换变量即可，可参考 example/App.vue\n// import '@xuanmo/v-form/packages/style/var.less'\n\n// 注册组件\n// 更多参数说明：https://github.com/D-xuanmo/v-form/blob/master/src/index.js#L6-L14\n/**\n * 设置地址选择组件数据 JSON，组件默认不注册数据\n * 如果需要自定义数据，参考此文件结构即可\n */\nimport ADDRESS_JSON from '@xuanmo/v-form/packages/Address/data.json'\nVue.use(VForm, {\n  addressJSON: ADDRESS_JSON\n})\n\n// 设置防抖时间，默认200ms\nVue.use(VForm, {\n  debounceTime: 200\n})\n```\n\n### 修改打包配置（注：如果组件引入采取的后编译需要配置这一项）\n```js\n// vue.config.js\nmodule.exports = {\n  transpileDependencies: [\n    '@xuanmo/v-form'\n  ]\n}\n```\n\n### 修改数据模型配置\n```js\nVue.use(VForm, {\n  primaryData: true\n})\n\n// 默认的数据模型\nconst model1 = [\n  {\n    key: 'text1',\n    value: '',\n    rules: {\n      label: '文字1',\n      type: 'VInput',\n      vRules: 'required|custom:@text2,@text3',\n      placeholder: '请输入文字',\n      errMsg: '请输入文字'\n    }\n  }\n]\n\n// primaryData 为 true 时的数据模型\nconst model2 = [\n  {\n    key: 'text1',\n    value: '',\n    label: '文字1',\n    type: 'VInput',\n    vRules: 'required|custom:@text2,@text3',\n    placeholder: '请输入文字',\n    errMsg: '请输入文字'\n  }\n]\n```\n\n### 注册全局自定义校验规则\n```js\n/**\n * 自定义校验规则示例，规则遵循VeeValidate规则扩展\n * 更多资料查看：https://logaretm.github.io/vee-validate/guide/basics.html#validation-provider\n */\nVue.use(VForm, {\n  validator: {\n    custom: {\n      // 此处定义的值可以在`validate`函数的第二个参数接收\n      params: ['length'],\n      message: '长度不能大于{length}',\n      validate: (value, { length }) =\u003e {\n        return value.length \u003c= length\n      }\n    },\n\n    // 关联校验，可将多个表单项的值做比对\n    target: {\n      params: ['target1', 'target2'],\n      message: '关联校验失败',\n      // validate 第三个参数为正在执行校验相关联的组件实例\n      validate: (value, { target1, target2 }, ctx) =\u003e {\n        return value === target1 \u0026\u0026 value === target2\n      }\n    }\n  }\n})\n```\n\n### HTML\n```html\n\u003cv-form v-model=\"value\" :model=\"model\"\u003e\u003c/v-form\u003e\n```\n\n## 可用组件（所有的组件的属性都继承自Vant-UI属性，不包含上传文件组件）\n|组件名|描述|\n|---|---|\n|VAddress|地址选择器|\n|VCheckbox|复选框|\n|VRadio|单选框|\n|VInput|输入框|\n|VNumberKeyboard|数字输入框|\n|VVerificationCode|短信验证码|\n|VDatePicker|时间选择器|\n|VDatePickerRange|时间区间选择器|\n|VSelect|下拉选择框|\n|VSwitch|开关按钮|\n|VText|纯文字展示|\n|VUpload|文件上传|\n\n### 关于自定义组件的使用（目前仅支持将该组件注册为全局组件使用）\n\u003e 在组件不能满足当前业务的需求时，可以使用 slot 或者自定义组件实现，slot 使用参考后续介绍\n\n#### 制作组件，具体实现可参考 example/components/FormItemTest.vue\n```js\n// 导入公用组件的 Mixin\nimport { vFormItemBaseMixin } from '@xuanmo/v-form'\nexport default {\n  name: 'FormItemTest',\n\n  // 使用 Mixin\n  mixins: [vFormItemBaseMixin],\n\n  methods: {\n    input(value) {\n      // 此方法必须调用，否则组件将不能接收数据\n      // 每次数据发生改变需要使用 e__input 方法对组件的数据进行上报\n      this.e__input(value)\n\n      // 如果需要发送自定义事件，可使用下边方法\n      this.__eventHandler('input', value)\n    }\n  }\n}\n```\n\n#### 全局注册组件\n```js\nimport Vue from 'vue'\nimport FormItemTest from 'path'\nVue.component(FormItemTest.name, FormItemTest)\n```\n\n#### 使用组件\n```js\nconst model = [\n  {\n    key: 'test',\n    value: '',\n    rules: {\n      label: '自定义组件',\n      // 传入组件名即可\n      type: 'FormItemTest',\n      placeholder: '点击输入',\n      vRules: 'required',\n      pattern: /^\\d+$/,\n      errorMsg: '自定义组件错误信息'\n    }\n  }\n]\n```\n\n## Attributes\n|字段名|说明|类型|默认值\n|---|---|---|---|\n|v-model(value)|获取组件处理完成的数据|object|{}|\n|model|数据模型(具体类型参考后续文档)|array|[]|\n|disabled|是否禁用表单|boolean|false|\n|label-width|label宽度|string|20%|\n|label-position|label对齐方式，可选：left/right|string|left|\n|label-color|label文字颜色|string|-|\n|show-label|是否显示label|boolean|true|\n|validator|局部校验规则|object|{}|\n\n## Methods\n|方法|说明|参数\n|---|---|---|\n|validate|对整个表单执行校验|(callback: Function, ErrorList: []) =\u003e void|\n|toggleFormItemVisible|切换表单单元的显示与隐藏状态|(key: string, visible: boolean) =\u003e void|\n|setModelItemOptions|设置表单options，目前支持的组件：VAddress、VCheckbox、VRadio、VSelect|(key, data)接受两个参数，1. 数据key，2. data为一个数组或者 `() =\u003e \u003cPromise\u003e[]`|\n\n## Events\n|事件名|说明|回调参数\n|---|---|---|\n|change|数据更改时触发|object{value,errorMsg,isValid}|\n|event|数据发生改变所发送的事件|object{event,formModel}|\n\n## Slots\n\u003e 组件可接受多个slot，用于替换当前行的表单组件，会为该slot传入该组件的原始数据，每个slot的name为当前行的key，注：该slot不继承所有校验规则\n```html\n\u003c!-- 示例如下 --\u003e\n\u003cv-form :model=\"model\"\u003e\n  \u003ctemplate v-slot:text=\"{ data }\"\u003e\n    \u003cvan-field v-model=\"data.value\"\u003e\u003c/van-field\u003e\n  \u003c/template\u003e\n\n  \u003c!-- 行label自定义slot，格式{key}-label --\u003e\n  \u003ctemplate #text-label\u003e\n    自定义label\n  \u003c/template\u003e\n\n  \u003c!-- 行扩展字段slot，格式{key}-extra --\u003e\n  \u003ctemplate #text-extra\u003e\n    extra\n  \u003c/template\u003e\n\u003c/v-form\u003e\n```\n\n## model数据格式\n\u003e 以下是一个简单的数据格式，生成一个输入框，详细使用见目录example\n\n```js\nconst model = [\n  // 以下三个文字输入示例为关联校验\n  // 关联校验采取{rule}:@{field},@{field}格式\n  // 接收字段采取@{rule}格式\n  {\n    key: 'text1',\n    value: '',\n    rules: {\n      label: '文字1',\n      type: 'VInput',\n      vRules: 'required|custom:@text2,@text3',\n      placeholder: '请输入文字',\n      errMsg: '请输入文字'\n    }\n  },\n\n  {\n    key: 'text2',\n    value: '',\n    rules: {\n      label: '文字2',\n      type: 'VInput',\n      vRules: 'required|@custom',\n      placeholder: '请输入文字',\n      errMsg: '请输入文字'\n    }\n  },\n\n  {\n    key: 'text3',\n    value: '',\n    rules: {\n      label: '文字3',\n      type: 'VInput',\n      vRules: 'required|@custom',\n      placeholder: '请输入文字',\n      errMsg: '请输入文字'\n    }\n  },\n\n  // 时间选择器\n  {\n    key: 'date',\n    value: Date.now(),\n    rules: {\n      label: '时间',\n      // 共4种类型：datetime、year-month、date、time\n      type: 'VDatePicker|datetime',\n      // 数据格式处理：timestamp时间戳，其他用法参考：https://github.com/D-xuanmo/datejs\n      valueFormat: 'yyyy-MM-dd'\n    }\n  },\n\n  // 图片上传\n  {\n    key: 'file',\n    // 用于显示列表\n    value: [{ path: 'https://upyun.xuanmo.xin/test/20200418225229.png' }],\n    rules: {\n      label: '文件上传',\n      type: 'VUpload',\n      action: 'xxx',\n      accept: 'image/png',\n      multiple: true,\n      name: 'file',\n      headers: {},\n      // 上传附加的数据\n      data: {\n        dir: 'test'\n      },\n      // 自定义配置项，用于指定url字段为某个属性值\n      props: {\n        url: 'path'\n      }\n    }\n  }\n]\n```\n\n## 组件 change 事件返回的数据\n|字段名|说明|\n|:---:|:---:|\n|value|所有的数据经过处理后会以一个对象存放在这个字段|\n|errorMsg|所有的校验失败的错误信息集合|\n|isValid|是否有通过所有的校验标识|\n```json\n{\n  \"value\": {},\n  \"errorMsg\": [],\n  \"isValid\": false\n}\n```\n\n## 示例图片\n\n![示例](./example.png)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd-xuanmo%2Fv-form","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fd-xuanmo%2Fv-form","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fd-xuanmo%2Fv-form/lists"}