驗證

運作方式

在 Inertia 中處理伺服器端驗證錯誤的方式,與經典的 XHR 驅動表單不同,後者需要您捕獲來自 422 回應的驗證錯誤,並手動更新表單的錯誤狀態 - 因為 Inertia 永遠不會收到 422 回應。相反,Inertia 的運作方式更像標準的完整頁面表單提交。以下是運作方式

首先,您使用 Inertia 提交您的表單。如果存在伺服器端驗證錯誤,您不會將這些錯誤作為 422 JSON 回應傳回。相反,您會將使用者重新導向(伺服器端)回他們先前所在的表單頁面,並在會話中快閃顯示驗證錯誤。某些框架,例如 Laravel,會自動執行此操作。

接下來,任何時候當這些驗證錯誤存在於會話中時,它們都會自動與 Inertia 共享,使其在客戶端作為頁面屬性可用,您可以在表單中顯示這些屬性。由於屬性是反應式的,它們會在表單提交完成時自動顯示。

最後,由於 Inertia 應用程式永遠不會產生 422 回應,因此 Inertia 需要另一種方式來判斷回應是否包含驗證錯誤。為此,Inertia 會檢查 page.props.errors 物件是否存在任何錯誤。如果存在錯誤,則會呼叫請求的 onError() 回呼,而不是 onSuccess() 回呼。

共享錯誤

為了使您的伺服器端驗證錯誤在客戶端可用,您的伺服器端框架必須透過 errors 屬性共享它們。Inertia 的第一方轉接器(例如 Laravel 轉接器)會自動執行此操作。對於其他框架,您可能需要手動執行此操作。請參閱您特定的伺服器端轉接器文件以獲取更多資訊。

顯示錯誤

由於驗證錯誤在客戶端以頁面元件屬性的形式提供,您可以根據它們是否存在有條件地顯示它們。請記住,當使用我們第一方的伺服器轉接器(例如 Laravel 轉接器)時,errors 屬性將自動提供給您的頁面。

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

defineProps({ errors: Object })

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" />
    <div v-if="errors.first_name">{{ errors.first_name }}</div>
    <label for="last_name">Last name:</label>
    <input id="last_name" v-model="form.last_name" />
    <div v-if="errors.last_name">{{ errors.last_name }}</div>
    <label for="email">Email:</label>
    <input id="email" v-model="form.email" />
    <div v-if="errors.email">{{ errors.email }}</div>
    <button type="submit">Submit</button>
  </form>
</template>
當使用 Vue 轉接器時,您也可以透過 $page.props.errors 物件存取錯誤。

重新填入輸入

雖然在 Inertia 中處理錯誤的方式與完整頁面表單提交類似,但 Inertia 提供了更多好處。事實上,您甚至不需要手動重新填入舊的表單輸入資料。

當發生驗證錯誤時,使用者通常會被重新導向回他們先前所在的表單頁面。而且,依預設,Inertia 會自動保留 元件狀態,用於 postput patchdelete 請求。因此,所有舊的表單輸入資料都與使用者提交表單時完全一樣。

因此,剩下的唯一工作是使用 errors 屬性顯示任何驗證錯誤。

錯誤包

如果您正在使用表單輔助程式,則無需使用錯誤包,因為驗證錯誤會自動限定在發出請求的表單物件的範圍內。

對於有多個表單的頁面,如果兩個表單共享相同的欄位名稱,則在顯示驗證錯誤時可能會遇到衝突。例如,假設有一個「建立公司」表單和一個「建立使用者」表單,它們都具有 name 欄位。由於這兩個表單都將顯示 page.props.errors.name 驗證錯誤,因此為任一表單中的 name欄位產生驗證錯誤會導致該錯誤同時出現在兩個表單中。

若要解決此問題,您可以使用「錯誤包」。錯誤包會將從伺服器傳回的驗證錯誤限定在特定於該表單的唯一金鑰內。繼續上面的範例,您可能會為第一個表單建立一個 createCompany 錯誤包,為第二個表單建立一個 createUser 錯誤包。

import { router } from '@inertiajs/vue3'

router.post('/companies', data, {
  errorBag: 'createCompany',
})

router.post('/users', data, {
  errorBag: 'createUser',
})

指定錯誤包會導致驗證錯誤從伺服器傳回,並且位於 page.props.errors.createCompanypage.props.errors.createUser 中。