跳转到主要内容

什么是 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()
form.validate('email');
防抖时间可以通过 setValidationTimeout() 调整。
form.setValidationTimeout(3000);
如果希望每次都校验文件,请使用 validateFiles()
form.validateFiles();
对数组输入可以使用通配符校验。
form.validate('users.*.email');

表单辅助函数

useForm() 可以整体管理提交与错误状态。
  • validating:正在发起校验请求
  • processing:正在提交
  • errors:错误列表
  • valid('field') / invalid('field'):字段校验状态
  • submit():常规提交
const submit = () => form.submit()
    .then(() => form.reset());

普通请求与 Precognition 请求的对比

下图展示了普通请求与 Precognition 请求的处理差异。

相关链接

最后修改于 2026年7月13日