Vue项目中如何为使用CInput的现有表单集成vee-validate v4校验?
你的代码需要针对vee-validate的规则做适配,操作步骤和修改后的代码如下:
前置确认
vee-validate v4仅支持Vue3,如果你当前项目使用的是Vue2,请执行以下命令安装适配Vue2的版本:npm install vee-validate@3 @vee-validate/rules@3 --save
以下是Vue3 + vee-validate v4的适配方案:
1. 安装校验规则包
执行命令安装官方预设的校验规则:npm install @vee-validate/rules --save
2. 完整修改后的代码
template部分
<template> <CRow> <CCol col="12" lg="6"> <CCard no-header> <CCardBody> <h3>创建笔记</h3> <CAlert :show.sync="dismissCountDown" color="primary" fade > ({{ dismissCountDown }}) {{ message }} </CAlert> <!-- 用Form组件包裹所有表单元素 --> <Form v-slot="{ errors, handleSubmit }" @submit="handleSubmit(store)"> <Field as="CInput" name="title" rules="required" label="标题" type="text" id="title" placeholder="请输入标题" v-model="note.title" ></Field> <!-- 错误提示 --> <span class="text-danger small" v-if="errors.title">{{ errors.title }}</span> <Field as="CInput" name="content" rules="required" textarea="true" label="内容" id="content" :rows="9" placeholder="请输入内容.." v-model="note.content" ></Field> <span class="text-danger small" v-if="errors.content">{{ errors.content }}</span> <Field as="CInput" name="applies_to_date" rules="required" label="适用日期" type="date" id="applies_to_date" v-model="note.applies_to_date" ></Field> <span class="text-danger small" v-if="errors.applies_to_date">{{ errors.applies_to_date }}</span> <Field as="CSelect" name="status_id" rules="required" id="status_id" label="状态" :value.sync="note.status_id" :plain="true" :options="statuses" > </Field> <span class="text-danger small" v-if="errors.status_id">{{ errors.status_id }}</span> <Field as="CInput" name="note_type" rules="required" label="笔记类型" type="text" id="note_type" v-model="note.note_type" ></Field> <span class="text-danger small" v-if="errors.note_type">{{ errors.note_type }}</span> <div id="app"> <ckeditor v-model="editorData" :config="editorConfig"></ckeditor> </div> <!-- 提交按钮改成submit类型 --> <CButton color="primary" type="submit">创建</CButton> <CButton color="primary" @click="goBack">返回</CButton> </Form> </CCardBody> </CCard> </CCol> </CRow> </template>
script部分
<script> import axios from 'axios'; import Vue from 'vue'; import CKEditor from 'ckeditor4-vue'; import Swal from "sweetalert2"; // 引入vee-validate组件和规则 import { Form, Field, defineRule } from 'vee-validate' import { required } from '@vee-validate/rules' // 注册必填校验规则,自定义中文提示 defineRule('required', (value) => { if (!value || (typeof value === 'string' && !value.trim()) || value === null) { return '该字段为必填项' } return true }) Vue.use(CKEditor); export default { name: 'EditUser', // 注册vee-validate组件 components: { Form, Field }, props: { caption: { type: String, default: '用户id' }, }, data: () => { return { note: { title: '', content: '', applies_to_date: '', status_id: null, note_type: '', }, statuses: [], message: '', dismissSecs: 7, dismissCountDown: 0, showDismissibleAlert: false, editorData: '', editorConfig: { // 编辑器配置 filebrowserImageBrowseUrl: Vue.prototype.$apiAdress+'/api/laravel-filemanager?token=' + localStorage.getItem("api_token"), filebrowserImageUploadUrl: Vue.prototype.$apiAdress+'/api/laravel-filemanager/upload?type=Images&_token=&token=' + localStorage.getItem("api_token"), filebrowserBrowseUrl: Vue.prototype.$apiAdress+'/api/laravel-filemanager?type=Files&token=' + localStorage.getItem("api_token"), filebrowserUploadUrl: Vue.prototype.$apiAdress+'/api/laravel-filemanager/upload?type=Files&_token=&token=' + localStorage.getItem("api_token"), height: 500, language: 'pl', //extraPlugins: 'facebookvideo, youtube, html5video', editorUrl: "facebookvideo.js", extraPlugins: 'a11yhelp,about,basicstyles,bidi,blockquote,clipboard,colorbutton,colordialog,contextmenu,copyformatting,dialogadvtab,div,editorplaceholder,elementspath,enterkey,entities,exportpdf,filebrowser,find,flash,floatingspace,font,format,forms,horizontalrule,htmlwriter,iframe,image,indentblock,indentlist,justify,language,link,list,liststyle,magicline,maximize,newpage,pagebreak,pastefromgdocs,pastefromlibreoffice,pastefromword,pastetext,preview,print,removeformat,resize,save,scayt,selectall,showblocks,showborders,smiley,sourcearea,specialchar,stylescombo,tab,table,tableselection,tabletools,templates,toolbar,undo,uploadimage, wysiwygarea,autoembed,image2,embedsemantic', image2_alignClasses: ['image-align-left', 'image-align-center', 'image-align-right'], image2_disableResizer: true, } } }, methods: { goBack() { this.$router.go(-1) }, // 校验通过后才会执行该提交方法,无需再手动校验 store() { let self = this; axios.post(this.$apiAdress + '/api/notes?token=' + localStorage.getItem("api_token"), self.note ) .then(function (response) { self.note = { title: '', content: '', applies_to_date: '', status_id: null, note_type: '', }; self.message = '笔记创建成功。'; self.showAlert(); }).catch(function (error) { if (error.response.data.message == 'The given data was invalid.') { self.message = ''; for (let key in error.response.data.errors) { if (error.response.data.errors.hasOwnProperty(key)) { self.message += error.response.data.errors[key][0] + ' '; } } self.showAlert(); } else { console.log(error); self.$router.push({path: 'login'}); } }); }, countDownChanged(dismissCountDown) { this.dismissCountDown = dismissCountDown }, showAlert() { this.dismissCountDown = this.dismissSecs }, }, mounted: function () { let self = this; axios.get(this.$apiAdress + '/api/notes/create?token=' + localStorage.getItem("api_token")) .then(function (response) { self.statuses = response.data; }).catch(function (error) { console.log(error); self.$router.push({path: 'login'}); }); } } </script>
核心改动说明
- 所有表单元素用
Form组件包裹,通过v-slot获取校验错误信息和提交处理方法 - 原有
CInput、CSelect组件通过Field的as属性绑定,每个字段设置唯一name属性和对应的校验规则 - 移除原有的手动校验逻辑
checkInputs,提交时Form会自动触发所有字段的校验,校验通过才会执行提交逻辑 - 每个字段下方添加错误提示区域,校验不通过时展示对应提示
内容的提问来源于stack exchange,提问作者tarafikttes
相关产品推荐
相关产品推荐

