介绍 Vue Formulate — 真正令人愉悦的表单创作。

2025-06-07

介绍 Vue Formulate — 真正令人愉悦的表单创作。

Vue Formulate已经发布 2 个月了,随着最新版本 (v2.3) 的发布,该项目已经有足够的发展势头,值得其创建者(我,Justin Schroeder)写一篇文章来解释它存在的原因、它的作用以及它的未来发展方向。

Vue Formulate 的简单示例

表格的问题

学习编程时,最激动人心的早期进步之一,莫过于让你的“Hello World”应用通过提示用户输入姓名来获得交互<input>。把这些精湛的 IO 技能运用到 Web 上,一切就变得轻而易举了!只需在标记中添加一个标签,就能轻松上手,对吧?嗯……还没那么快。

在过去的两个月里,我收到了很多关于 Vue Formulate 的问题。不出所料,最常见的问题之一就是“HTML 有什么问题?”

当然,HTML 本身没有问题,就像 Vue 和 React 之前的 JavaScript 一样(我知道,我知道,Vanilla 纯粹主义者肯定怒火中烧)。HTML、React、Vue……这些都无所谓——但现实是:创建高质量的表单需要深思熟虑。标签、帮助文本、验证、内联文件上传和可访问性只是开发人员需要考虑的几个方面。这几乎不可避免地会导致代码库中充斥着大量的复制粘贴和样板标记。

还有其他问题。例如,HTML 验证就非常有限。如果您想异步检查用户名是否已被使用,该怎么办?如果您想拥有样式良好的验证错误信息,该怎么办?如果您想让用户能够在购票时添加更多参会者,该怎么办?所有这些功能对于原生 HTML/React/Vue 来说,如果不付出相当大的努力,都无法实现。此外,在处理这些不同的功能时保持高质量水平,其次才是让表单正常工作。这对于库来说是一片沃土,可以帮助提高开发人员的幸福感,同时提高质量和可访问性。

Vue Formulate 为何与众不同?

Vue Formulate 远非第一个解决这些问题的库。我们社区中的老朋友多年来一直在努力解决这些问题:vue-forms、VeeValidate、Vuelidate,甚至像 Vuetify 这样的一些 UI 框架也致力于帮助开发者编写更好的表单。这些都是很棒的库,如果它们适合你的项目,我并不建议你使用它们。然而,Vue Formulate 通过两个特定的目标来解决同样的问题:

  1. 改善开发人员的表单创作体验。
  2. 提高最终用户的表单质量。

为了提供卓越的开发者体验,Vue Formulate 需要专注于成为一个全面的表单创作解决方案。它不能仅仅是一个验证器,也不渴望成为一个完整的 UI 库。相反,这些指导原则造就了高度一致的组件优先 API,专注于一流的表单创作。为此,Vue Formulate 中的每个输入都使用相同的组件进行创作<FormulateInput>,从而消除了 HTML 默认元素(例如 、 等)中的不一致问题<input>在 Vue Formulate 中,您只需告诉<textarea>应该是什么类型的输入——文本输入()和选择输入( )甚至可以通过动态更改 prop 来动态切换。<select><FormulateInput><FormulateInput type="text"><FormulateInput type="select">type

你可能会问,为什么这样更好?因为它更容易记住,书写速度更快,还能减少错误。我们绝对不应该忽视这些实实在在的生活质量改善……但这当然不是全部。

通过确保所有输入都遵循单一组件接口,我们可以实现更强大的增强功能,例如自动标签、声明式验证、表单生成、自动可访问性属性以及对复杂自定义输入的支持。这使得FormulateInput组件在拥有强大功能的同时,也能保持易于使用的 API。不妨思考一下,这两个输入组件使用 Vue Formulate 编写时有多么相似,但它们的实际 HTML 实现却有多么不同:

<FormulateInput
  type="email"
  name="email"
  label="Enter your email address"
  help="We’ll send you an email when your ice cream is ready"
  validation="required|email"
/>
<FormulateInput
  type="checkbox"
  name="flavor"
  label="Pick your 2 favorite flavors"
  validation="min:2,length"
  :options="{
   vanilla: 'Vanilla',
   chocolate: 'Chocolate',
   strawberry: ’Strawberry',
   apple: 'Apple'
  }"
/>
Enter fullscreen mode Exit fullscreen mode

现在,请注意该示例中我们不必处理的一些事情:

  • <label>元素输入是自动生成的,并<input>通过自动生成的 ID 链接到元素(如果需要,请指定)。
  • 帮助文本在适当的位置生成,并且输入与其链接aria-describedby
  • 我们添加了实时输入验证,而无需明确输出错误。
  • 多个复选框被呈现并且它们的值链接在一起。
  • 复选框的标签自动调整其位置。

通过将输入整合到单个FormulateInput组件中,我们显著提升了开发者的开发体验,同时创建了一个强大的钩子,用于为这些输入添加新的特性和功能。此外,当需要升级到 Vue 3 的 Composition API 时,Vue Formulate 的组件优先 API 意味着开发者无需重构模板代码中的任何内容。

很好,但是我的表格在哪里?

我已经解释了 Vue Formulate 的用途及其独特的输入处理方式,但表单本身呢?让我们考虑一下原生<form>元素的用途:通过聚合输入元素的值,将用户的输入传输到服务器。这在 Vue Formulate 中是什么样的?几乎和你预期的完全一样:

<template>
  <FormulateForm
    @submit="login"
  >
    <FormulateInput
      type="email"
      name="email"
      label="Email address"
      validation="required|email"
    />
    <FormulateInput
      type="password"
      name="password"
      label="Password"
      validation="required" 
    />
    <FormulateInput label="Login" type="submit" />
  </FormulateForm>
</template>

<script>
export default {
  methods: {
    login (data) {
      /* do something with data when it passes validation:
       * { email: 'zzz@zzz.com', password: 'xyz' }
       */
      alert('Logged in')
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

很好,数据聚合就像普通表单一样工作,但这里还没有任何“响应式”的东西。啊,让我们把一个添加v-model到表单上——然后——瞧!我们得到了一个完全响应式的对象,并且表单中包含了所有数据。

<template>
  <FormulateForm
    @submit="login"
    v-model="values"
  >
    <FormulateInput
      type="email"
      name="email"
      label="Email address"
      validation="required|email"
    />
    <FormulateInput
      type="password"
      name="password"
      label="Password"
      validation="required" 
    />
    <FormulateInput label="Login" type="submit" />
    <pre>{{ values }}</pre>
  </FormulateForm>
</template>

<script>
export default {
  data () {
   return {
     values: {}
   }
  },
  methods: {
    login (data) {
      /* do something with data:
       * { email: 'zzz@zzz.com', password: 'xyz' }
       */
      alert('Logged in')
    }
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

是的,v-model这意味着双向数据绑定。您可以通过更改单个对象的属性将值写入表单中的任何输入框。目标要小,失误要小——所以,让我们努力让“它正常工作”成为默认的开发者体验。

插槽、自定义输入、插件 — 天哪!

本文只是个简介,不能替代完整的文档,但如果忽略一些我最喜欢的扩展功能,那就太不公平了。表单创作工具需要灵活——凡事都有例外情况,对吧?Vue Formulate 高度自命不凡的组件优先 API 似乎与灵活性格格不入,但实际上,一致的 API 正是高度灵活架构的核心所在。

Slots 是一个很好的例子,它体现了一致性如何发挥作用。Vue Formulate 输入的核心是一个综合context对象,它几乎决定了输入的所有内容。模型、验证错误、标签值、帮助文本以及许多其他内容都是这个对象的成员。由于每个输入都有一致的 API,因此每个输入都有一个一致的上下文对象。

虽然使用作用域插槽的灵活性很高,但它们可能会损害表单代码的一致性和可读性。为了解决这个问题,Vue Formulate 还提供了覆盖每个插槽默认值的功能。我们称之为“插槽组件”,它们对于维护简洁一致的创作 API 至关重要。想要为每个标签添加示例工具提示吗?没问题。您可以替换项目中每个输入框的标签插槽中的默认值,而无需使用作用域插槽或将组件包装在模板中。

如果您觉得创建自定义输入类型更好,也可以这样做!自定义输入可以让表单编写变得非常流畅,只需选择您自己的输入type并将其注册到 Vue Formulate 即可。您的自定义输入将获得验证、标签、帮助文本、模型绑定等开箱即用的功能。更棒的是,创建自定义输入后,您可以轻松地将其转换为插件,与团队成员或更大的社区共享。

你去的地方就是我想去的地方……

在优秀的 Honeypot Vue 纪录片中,Thorsten Lünborg 总结了我认为 Vue 取得巨大成功的首要原因:

Vue.js 从一开始的重点就是,框架不仅仅是代码。它不是那种“这是库,这是文档,说明了它是如何工作的,现在你来解决剩下的问题”之类的。

本质上,Vue 核心团队愿意深入开发者最痛点的地方。因此,他们创建了一个不仅优雅,而且让实际开发者乐于使用的框架。Vue Formulate 秉承了这种精神;用令人愉悦的表单创作解决方案来满足开发者的痛点。我们相信我们已经为 90% 的用户铺平了道路——但如果你的道路人迹罕至,并且你发现自己处于边缘情况——请大声说出来。我们倾听你的心声。


如果您感兴趣,请访问vueformulate.com。您可以在 Twitter 上关注我Justin Schroeder,以及我的共同维护者Andrew Boyd

文章来源:https://dev.to/justinschroeder/introducing-vue-formulate-truly-delightful-form-authoring-56f5
PREV
JavaScript 从 ES6 到今天
NEXT
介绍 AutoAnimate — 用一行代码为您的应用添加动作。