什么是 Precognition
Precognition 是一种在表单提交之前执行服务端校验的机制。
你无需在前端重复定义校验规则,可以直接使用 Laravel 的规则。
与普通请求不同,Precognition 请求会执行路由中间件与 Form Request 的校验,但不会执行控制器方法主体。
因此非常适合在输入过程中进行实时校验。
在 Laravel 13 中,后端无需额外安装 laravel/precognition。
你只需要安装用于前端的辅助包。
- Vue:
laravel-precognition-vue
- React:
laravel-precognition-react
- Alpine.js:
laravel-precognition-alpine
npm install laravel-precognition-vue
npm install laravel-precognition-react
npm install laravel-precognition-alpine
Inertia 自 2.3 起内置支持 Precognition,Inertia 3 也可直接使用。
在使用 Inertia 表单时,通常不需要额外引入 laravel-precognition-vue / laravel-precognition-react。
后端配置
给路由添加 HandlePrecognitiveRequests 中间件。
将校验规则集中在 Form Request 中是实践性的做法。
使用 Form Request 更便于规则复用和职责分离。
use App\Http\Requests\StoreUserRequest;
use Illuminate\Foundation\Http\Middleware\HandlePrecognitiveRequests;
use Illuminate\Support\Facades\Route;
Route::post('/users', function (StoreUserRequest $request) {
// 只有在真正提交时才会执行此处
})->middleware([HandlePrecognitiveRequests::class]);
如果你自定义的中间件有副作用,请在 Precognition 时跳过。
public function handle(Request $request, Closure $next): mixed
{
if (! $request->isPrecognitive()) {
Interaction::incrementFor($request->user());
}
return $next($request);
}
前端集成
Alpine.js(Blade)
<form x-data="{
form: $form('post', '/users', { name: '', email: '' }),
}">
@csrf
<input x-model="form.name" @change="form.validate('name')" />
<template x-if="form.invalid('name')">
<div x-text="form.errors.name"></div>
</template>
</form>
Vue(Inertia.js)
<script setup>
import { useForm } from 'laravel-precognition-vue';
const form = useForm('post', '/users', {
name: '',
email: '',
});
</script>
<template>
<input v-model="form.name" @change="form.validate('name')" />
<div v-if="form.invalid('name')">{{ form.errors.name }}</div>
</template>
React(Inertia.js)
import { useForm } from 'laravel-precognition-react';
const form = useForm('post', '/users', {
name: '',
email: '',
});
<input
value={form.data.name}
onChange={(e) => form.setData('name', e.target.value)}
onBlur={() => form.validate('name')}
/>
使用 Axios 的原生 JS
Precognition 库使用 Axios。
如果你希望使用已有的 Axios 实例,可以通过 client.use() 替换。
import Axios from 'axios';
import { client } from 'laravel-precognition-vue';
window.axios = Axios.create();
window.axios.defaults.headers.common['Authorization'] = authToken;
client.use(window.axios);
控制校验时机
对逐个字段的校验使用 validate()。
防抖时间可以通过 setValidationTimeout() 调整。
form.setValidationTimeout(3000);
如果希望每次都校验文件,请使用 validateFiles()。
对数组输入可以使用通配符校验。
form.validate('users.*.email');
表单辅助函数
useForm() 可以整体管理提交与错误状态。
validating:正在发起校验请求
processing:正在提交
errors:错误列表
valid('field') / invalid('field'):字段校验状态
submit():常规提交
const submit = () => form.submit()
.then(() => form.reset());
普通请求与 Precognition 请求的对比
下图展示了普通请求与 Precognition 请求的处理差异。
相关链接