使用 Alpine.js 的高级表单

本文中的文本由ChatGPT和DeepL Write部分生成,并由我们进行校正和修改。

如果您还不熟悉如何使用 Alpine.js 处理表单,您可以在我们关于此主题的第一篇文章《使用 Alpine.js 的交互式表单》中复习一下您的知识。

在我们第一篇关于使用 Alpine.js 进行交互式表单的文章中,我们已经指出,除了表单中服务器端信息的一般显示之外,Alpine.js 还可以用于影响单个元素。

应广大民众的需求,我们决定在这篇后续文章中专门讨论这个主题,并展示如何使用信息和状态通过 Alpine.js 验证表单的示例。

设置

在本演示中,我们使用 Astro Boilerplate,

我们在之前的文章中已经详细介绍过。

如果我们的样板不适合您,那也没关系。验证表单条目的步骤适用于任何使用 Alpine.js 的项目。

集成 Alpine.js 的方法

为了能够在进一步的实施过程中从 Alpine.js 访问所需的数据和方法,首先声明这些数据和方法,以避免在进一步的实施过程中出现错误。

表单.ts

`form()` 控制 `loading` 状态,并通过 `submit()` 方法保存服务器发送的 `Response`,该方法在表单提交时执行。

还包括一个虚构的“fakeResponse()”,它从我们虚构的后端“接收”示例性和简化的验证错误。

import { sleep } from "../utilities";

export const form = () => ({
  loading: false,
  response: null as unknown,

  async submit(event: SubmitEvent) {
    this.loading = true;
    this.response = null;
    const formData = new FormData(event.target as HTMLFormElement);

    /**
     * Replace the following fake response with your `fetch` request and
     * receive the validated results from the server side as JSON.
     *
     * Make sure you add the necessary attributes to the `'
     * elements to perform client-side validation as well.
     */

    const fakeResponse = async () => {
      await sleep(1000); // Mock response time

      return {
        errors: {
          // [input.name]: "message string"
          username: "Username is alrady taken",
          password: "Password is too short",
        },
      };
    };

    this.response = await fakeResponse();
    this.loading = false;
  },
});

`Response` 必须包含一个 `error` 对象,其中每个键值对由输入元素的名称和相关的验证错误组成。

输入.ts

`input.ts` 通过 `validate()` 方法处理输入元素的验证错误的显示,该方法通过属性集成,以便在提交表单时重新计算要显示的数据。

export const input = () => ({
  error: null as unknown,

  validate() {
    if (!this.response?.errors?.[this.$el.name]) return (this.error = null);
    this.error = this.response.errors[this.$el.name];
  },
});

全局变量.ts

最后,为此步骤导入为 Alpine.js 声明的方法,并在 EventListener `alpine:init` 中注册,以便能够访问所需的范围。

import Alpine from "alpinejs";
import { app } from "./alpine/app";
import { form } from "./alpine/form";
import { input } from "./alpine/input";

// Await Alpine.js initialization
document.addEventListener("alpine:init", () => {
  Alpine.data("app", app);
  Alpine.data("form", form);
  Alpine.data("input", input);
});

Alpine.start();

声明可选的实用方法

为了我们也可以使用输入元素的名称作为标签,我们创建了方法“capitalize”,它将以 kebab-case () 编写的字符串拆分并将每个单词大写。

如果您决定不使用大写,则必须删除“input.astro”组件中的相应引用

export const capitalize = (string: string) => {
  return string
    .split("-")
    .map((word) => word[0].toUpperCase() + word.substring(1))
    .join(" ");
};

在 Astro 中创建页面和组件

在下一步中,我们将创建表单所需的页面和组件。我们定义一个``组件并将其集成到表单块中。

输入.astro

`input.astro` 结合了元素 `' 和 ' ' 在一个组件中,还包含验证错误的表示,这些表示通过 Alpine 上下文 'input' 进行映射。

---
import { capitalize } from "@/scripts/utilities"

const { name, ...props } = Astro.props
---

指数.astro

`index.astro` 代表我们的表单块,并使用预定义组件 `'并用'表单'上下文补充其逻辑,以便可以显示来自'响应'对象的错误。

虽然我们的组件`` 处理验证错误的显示,我们将各个输入元素的 `disabled` 属性绑定到 `loading` 状态,以防止在处理过程中多次提交表单。

---
import Root from "@/layouts/root.astro"
import Input from "@/components/input.astro"

const meta = {
  title: "Advanced forms with Alpine.js"
}
---


  

总结

通过 Alpine.js,我们演示了如何将后端的验证错误动态地显示在表单中,以及输入元素如何对浏览器中的相应事件做出反应。