表单

提交表单

虽然可以使用 Inertia 进行传统的 HTML 表单提交,但并不推荐,因为它们会导致全页面重新加载。相反,最好拦截表单提交,然后使用 Inertia 进行 请求

<script setup>
import { reactive } from 'vue'
import { router } from '@inertiajs/vue3'

const form = reactive({
  first_name: null,
  last_name: null,
  email: null,
})

function submit() {
  router.post('/users', form)
}
</script>

<template>
  <form @submit.prevent="submit">
    <label for="first_name">First name:</label>
    <input id="first_name" v-model="form.first_name" />
    <label for="last_name">Last name:</label>
    <input id="last_name" v-model="form.last_name" />
    <label for="email">Email:</label>
    <input id="email" v-model="form.email" />
    <button type="submit">Submit</button>
  </form>
</template>

如您在上面的示例中所见,使用 Inertia 时,通常不需要像手动进行 XHR / fetch 请求那样在客户端检查表单响应。

相反,您的服务器端路由 / 控制器通常会发出 重定向 响应。当然,没有什么能阻止您将用户重定向回他们之前所在的页面。使用这种方法,处理 Inertia 表单提交的感觉与处理传统的 HTML 表单提交非常相似。

class UsersController extends Controller
{
    public function index()
    {
        return Inertia::render('Users/Index', [
          'users' => User::all(),
        ]);
    }

    public function store(Request $request)
    {
        User::create($request->validate([
          'first_name' => ['required', 'max:50'],
          'last_name' => ['required', 'max:50'],
          'email' => ['required', 'max:50', 'email'],
        ]));

        return to_route('users.index');
    }
}

服务器端验证

在 Inertia 中处理服务器端验证错误的方式与处理手动 XHR / fetch 请求的错误略有不同。在进行 XHR / fetch 请求时,通常会检查响应是否有 422 状态代码,并手动更新表单的错误状态。

但是,使用 Inertia 时,您的服务器永远不会返回 422 响应。相反,正如我们在上面的示例中看到的,您的路由 / 控制器通常会返回重定向响应 - 就像传统的全页面表单提交一样。

有关使用 Inertia 处理和显示验证错误的完整讨论,请参阅 验证 文档。

表单助手

由于表单操作非常常见,Inertia 包含一个表单助手,旨在帮助减少处理典型表单提交所需的样板代码量。

<script setup>
import { useForm } from '@inertiajs/vue3'

const form = useForm({
  email: null,
  password: null,
  remember: false,
})
</script>

<template>
  <form @submit.prevent="form.post('/login')">
    <!-- email -->
    <input type="text" v-model="form.email">
    <div v-if="form.errors.email">{{ form.errors.email }}</div>
    <!-- password -->
    <input type="password" v-model="form.password">
    <div v-if="form.errors.password">{{ form.errors.password }}</div>
    <!-- remember me -->
    <input type="checkbox" v-model="form.remember"> Remember Me
    <!-- submit -->
    <button type="submit" :disabled="form.processing">Login</button>
  </form>
</template>

要提交表单,您可以使用 getpostputpatchdelete 方法。

form.submit(method, url, options)
form.get(url, options)
form.post(url, options)
form.put(url, options)
form.patch(url, options)
form.delete(url, options)

提交方法支持所有典型的 访问选项,例如 preserveStatepreserveScroll 和事件回调,这些回调对于在成功提交表单后执行任务很有用。例如,您可以使用 onSuccess 回调将输入重置为其原始状态。

form.post('/profile', {
  preserveScroll: true,
  onSuccess: () => form.reset('password'),
})

如果需要在将表单数据发送到服务器之前修改它,可以通过 transform() 方法来实现。

form
  .transform((data) => ({
    ...data,
    remember: data.remember ? 'on' : '',
  }))
  .post('/login')

您可以使用 processing 属性来跟踪表单当前是否正在提交。这对于通过禁用提交按钮来防止重复提交表单很有用。

<button type="submit" :disabled="form.processing">Submit</button>

如果您的表单正在上传文件,则可以通过 progress 属性访问当前进度事件,从而可以轻松显示上传进度。

<progress v-if="form.progress" :value="form.progress.percentage" max="100">
  {{ form.progress.percentage }}%
</progress>

如果有表单验证错误,则可以通过 errors 属性访问它们。在构建 Laravel 支持的 Inertia 应用程序时,当您的应用程序抛出 ValidationException 实例时,表单错误会自动填充,例如使用 $request->validate() 时。

<div v-if="form.errors.email">{{ form.errors.email }}</div>
有关表单验证和错误的更详细讨论,请参阅 验证文档

要确定表单是否有任何错误,可以使用 hasErrors 属性。要清除表单错误,请使用 clearErrors() 方法。

// Clear all errors...
form.clearErrors()

// Clear errors for specific fields...
form.clearErrors('field', 'anotherfield')

如果您使用的是客户端输入验证库或手动进行客户端验证,则可以使用 setErrors() 方法在表单上设置您自己的错误。

// Set a single error...
form.setError('field', 'Your error message.');

// Set multiple errors at once...
form.setError({
  foo: 'Your error message for the foo field.',
  bar: 'Some other error for the bar field.'
});
与实际的表单提交不同,在表单实例上手动设置错误时,页面的道具保持不变。

当表单成功提交时,wasSuccessful 属性将为 true。除此之外,表单还有一个 recentlySuccessful 属性,在成功提交表单后的两秒钟内,该属性将设置为 true。此属性可用于显示临时成功消息。

要将表单的值重置回其默认值,可以使用 reset() 方法。

// Reset the form...
form.reset()

// Reset specific fields...
form.reset('field', 'anotherfield')

如果您的表单默认值已过时,您可以使用 defaults() 方法更新它们。然后,下次调用 reset() 方法时,表单将重置为正确的值。

// Set the form's current values as the new defaults...
form.defaults()

// Update the default value of a single field...
form.defaults('email', '[email protected]')

// Update the default value of multiple fields...
form.defaults({
  name: 'Updated Example',
  email: '[email protected]',
})

要确定表单是否有任何更改,您可以使用 isDirty 属性。

<div v-if="form.isDirty">There are unsaved form changes.</div>

要取消表单提交,请使用 cancel() 方法。

form.cancel()

要指示 Inertia 将表单数据和错误存储在 历史状态 中,您可以在实例化表单时提供一个唯一的表单键作为第一个参数。

import { useForm } from '@inertiajs/vue3'

const form = useForm('CreateUser', data)
const form = useForm(`EditUser:${user.id}`, data)

文件上传

在进行包含文件的请求或表单提交时,Inertia 会自动将请求数据转换为 FormData 对象。

有关文件上传的更详细讨论,请参阅 文件上传文档

XHR / fetch 提交

使用 Inertia 提交表单非常适合大多数情况;但是,如果您需要对表单提交有更多控制,您可以自由地使用您选择的库进行普通的 XHR 或 fetch 请求。