表單

提交表單

雖然可以使用 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.'
});
與實際的表單提交不同,當手動在表單實例上設定錯誤時,頁面的 props 會保持不變。

當表單成功提交時,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', 'updated-default@example.com')

// Update the default value of multiple fields...
form.defaults({
  name: 'Updated Example',
  email: 'updated-default@example.com',
})

若要判斷表單是否有任何變更,您可以使用 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 請求。