{"id":21525852,"url":"https://github.com/bkwld/vue-form","last_synced_at":"2026-03-19T20:44:12.468Z","repository":{"id":146043422,"uuid":"422251442","full_name":"BKWLD/vue-form","owner":"BKWLD","description":"Accessible, stylable forms with validation","archived":false,"fork":false,"pushed_at":"2023-10-12T08:31:15.000Z","size":564,"stargazers_count":0,"open_issues_count":5,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-30T14:16:56.439Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/BKWLD.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":"2021-10-28T15:10:45.000Z","updated_at":"2022-06-30T23:07:33.000Z","dependencies_parsed_at":"2023-10-12T19:08:44.810Z","dependency_job_id":null,"html_url":"https://github.com/BKWLD/vue-form","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/BKWLD/vue-form","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BKWLD%2Fvue-form","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BKWLD%2Fvue-form/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BKWLD%2Fvue-form/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BKWLD%2Fvue-form/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BKWLD","download_url":"https://codeload.github.com/BKWLD/vue-form/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BKWLD%2Fvue-form/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28807083,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T06:25:51.065Z","status":"ssl_error","status_checked_at":"2026-01-27T06:25:50.640Z","response_time":168,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":[],"created_at":"2024-11-24T01:38:40.822Z","updated_at":"2026-01-27T07:03:16.821Z","avatar_url":"https://github.com/BKWLD.png","language":"Vue","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n## Caveats\n\n- This package is designed to be used by a Cloak app.\n- Included styles are written in Stylus only\n- Stylus expects `bukwild-stylus-library` mixins to already be imported\n\n## Getting Started\n\nAdd this to `nuxt.config.coffee`, so that vue-form's components are registered globally in Nuxt:\n```coffee\nbuildModules: ['@nuxt/components', 'vue-form/nuxt']\n```\n\nBuild your form:\n```pug\nvue-form(\n  id='newsletter'\n  :submit='onSubmit'\n  #default=\"{success, error, submitting, submitted}\"\n)\n  \n  //- Form message\n  .message(v-if='success') Thanks!\n  .message(v-else-if='error') Error.\n  .message(v-else) Sign up\n\n  //- Form Fields\n  //- Use any DOM structure as long as the fields\n  //- are a descendant of vue-form.\n  .fields(v-if='!submitted')\n\n    input-field(\n      label=\"Your Name\"\n      name=\"name\"\n      :rules='[\"required\"]'\n    )\n\n    input-field(\n      label=\"Email Address\"\n      name=\"email\"\n      placeholder=\"Your email address\"\n      :rules='[\"email\"]'\n    )\n    \n    button(\n      type='submit'\n    ) Sign up\n```\n\nAdd your submit handler:\n\n```coffee\nmethods:\n  onSubmit: (form) -\u003e \n    # Executed only if all input has passed client-side validation.\n    # `form` is an object with all your field data\n    \n    # Can be async\n    await @uploadToSomewhere(form)\n    \n    # vue-form catches errors, sets @error and @submitted to true, and logs the error to console as a console.warn\n    throw(\"Couldn't connect to remote service\")\n```\n\n\n## Custom Styling\n\nTo skin vue-form, you have two options:\n\n* Import vue-form's Stylus stylesheet into your component, and create a theme by overriding a few Stylus variables.\n\n* Start from scratch.  Vue-form's components include no styles by default.  This is by design, to give you the most flexibility.\n\nTo import vue-form's Stylus stylesheet and create a theme:\n\n```stylus\n\u003e\u003e\u003e  // 👈 Deep selector is required if your component styles are scoped\n  // Customize variables (see \"vue-form/src/assets/definitions.styl\")\n  form-color-base = white\n  form-bkg-base = grey\n  \n  // Import vue-form styles\n  @import '~vue-form/index.styl'\n```\n\n## Validation\n\nEach field validates itself on blur and submit, and shows/hides its own validation message.\n\nFields have a `rules` prop that accepts an array of strings or functions.  \n\nStrings represent preset validators included in this package:\n\n- \"email\":  Must be a valid email\n- \"required\": Must not be empty or unchecked.\n- \"url\": Must be a valid URL.\n- \"notUrl\"\n- \"ipAddress\":  Must be a valid IPv4 or IPv6 address.\n- \"notIpAddress\"\n\nFunctions are your custom validator functions.  A validator function must:\n\n- Accept one argument (the field value)\n- Return true (valid), false (invalid), or a string (invalid, with a custom validation error message)\n\n## FAQ\n\n### Why does this package use an event bus?\n\nMost Vue form libraries manage field values with a direct data binding.  The result is that each field's `name` is repeated up to four times:\n\n```\n\u003ctemplate\u003e\nvue-form(:form='form' :rules='rules')\n  input-field(\n    v-model=\"form.email\" // 👈 Field name (1st time)\n    label=\"Email Address\"\n    name=\"email\" // 👈 Field name (2nd time, for the input label's `for` attribute)\n  )\n  ...\n\u003c/template\u003e\nexport default\n  data: -\u003e\n    form: {\n      name: \"\" // 👈 Field name (3rd time, or else this property is not reactive)\n    } \n\n    rules: {\n      email: ['required', 'email']  // 👈 Field name (4th time, if we want validation rules)\n    }\n```\n\nForgetting or misspelling any of these four `name` instances will break something important.  In a big form, this can be a lot to manage.\n\nIn this form library, the form component and the fields communicate directly using an event bus (`tiny-emitter` library, so it's Vue 3 compatible).  This is a tradeoff: it introduces complexity (it's a manual data binding outside of Vue), but it allows us to eliminate this 4x `name` repetition.  It also lets us make `rules` a prop on each field which is a nice API.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbkwld%2Fvue-form","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbkwld%2Fvue-form","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbkwld%2Fvue-form/lists"}