Laravel验证有unique方法,Vue Vee Validate无,如何在v-validate中使用?
如何在VeeValidate中实现Laravel风格的Unique验证?
嘿,这个问题我之前做项目的时候刚好碰到过!VeeValidate本身确实没有内置像Laravel那样的unique验证规则,但我们完全可以通过自定义异步规则来实现一模一样的效果,下面一步步给你拆解:
步骤1:自定义VeeValidate的Unique规则
因为唯一性校验需要和后端数据库交互,所以必须定义异步验证规则。下面分VeeValidate 3.x和4.x两个常用版本来写:
针对VeeValidate 3.x
先导入extend方法,然后定义规则:
import { extend } from 'vee-validate'; import axios from 'axios'; extend('unique', { // 异步验证函数:value是输入值,args是规则传入的参数(表名、字段名等) validate: async (value, args) => { const { table, column, ignoreId } = args; try { // 发送请求到后端验证接口 const response = await axios.post('/api/validate-unique', { value, table, column, ignore_id: ignoreId // 编辑场景下用来排除当前记录ID }); // 后端返回true表示值唯一,验证通过 return response.data.valid; } catch (error) { // 请求失败默认验证不通过 return false; } }, // 错误提示,{_field_}会自动替换为表单字段名 message: '该{_field_}已经存在,请更换', // 标记为异步规则 async: true });
针对VeeValidate 4.x
4.x版本用defineRule来定义规则:
import { defineRule } from 'vee-validate'; import axios from 'axios'; defineRule('unique', async (value, { table, column, ignoreId }) => { try { const response = await axios.post('/api/validate-unique', { value, table, column, ignore_id: ignoreId }); // 验证通过返回true,不通过返回错误提示文本 return response.data.valid ? true : '该{field}已经存在,请更换'; } catch (error) { return '验证失败,请稍后重试'; } });
步骤2:编写Laravel后端验证接口
我们需要在Laravel里写一个接口,接收前端的验证请求,查询数据库判断值是否唯一:
首先在routes/api.php里添加路由:
use Illuminate\Http\Request; use Illuminate\Support\Facades\DB; Route::post('/validate-unique', function (Request $request) { // 先验证前端传入的参数合法性 $request->validate([ 'value' => 'required', 'table' => 'required|string', 'column' => 'required|string', 'ignore_id' => 'nullable|integer' ]); // 构建查询 $query = DB::table($request->table) ->where($request->column, $request->value); // 如果是编辑场景,排除当前记录的ID if ($request->filled('ignore_id')) { $query->where('id', '!=', $request->ignore_id); } // 判断是否存在重复值 $exists = $query->exists(); // 返回结果:!exists 表示值唯一,验证通过 return response()->json(['valid' => !$exists]); });
步骤3:在Vue组件中使用自定义规则
现在就可以像用VeeValidate内置规则一样使用我们的unique规则了:
3.x版本组件示例
<template> <div> <!-- 新增场景:验证rubrics表的title字段唯一 --> <input v-model="form.title" v-validate="'required|unique:{table: \'rubrics\', column: \'title\'}" name="title" placeholder="请输入标题" > <!-- 编辑场景:排除当前记录的ID --> <!-- <input v-model="form.title" v-validate="'required|unique:{table: \'rubrics\', column: \'title\', ignoreId: ' + currentRubricId + '}" name="title" placeholder="请输入标题" > --> <!-- 显示错误信息 --> <span class="error" v-show="errors.has('title')"> {{ errors.first('title') }} </span> </div> </template> <script> export default { data() { return { form: { title: '' }, currentRubricId: 1 // 编辑时的当前记录ID }; } }; </script>
4.x版本组件示例(Composition API)
<script setup> import { useForm } from 'vee-validate'; const currentRubricId = 1; // 编辑时的当前记录ID // 定义表单验证规则 const { handleSubmit, errors, values } = useForm({ initialValues: { title: '' }, validationSchema: { // 新增场景 title: 'required|unique:{table: "rubrics", column: "title"}' // 编辑场景 // title: `required|unique:{table: "rubrics", column: "title", ignoreId: ${currentRubricId}}` } }); // 提交处理 const onSubmit = handleSubmit((formValues) => { console.log('提交数据:', formValues); // 这里写提交到后端的逻辑 }); </script> <template> <form @submit="onSubmit"> <input v-model="values.title" name="title" placeholder="请输入标题"> <span class="error" v-if="errors.title">{{ errors.title }}</span> <button type="submit">提交</button> </form> </template>
这样一套流程下来,就完全实现了和Laravel里unique:rubrics,title一样的验证效果,不管是新增还是编辑场景都能覆盖到。
内容的提问来源于stack exchange,提问作者Andrey
相关产品推荐
相关产品推荐

