Blazor和Vue对比学习(基础1.9):表单输入绑定和验证,VeeValidate和EditFrom
这是基础部分的最后一章,内容比较简单,算是为基础部分来个HappyEnding。我们分三个部分来学习:
- 表单输入绑定
- Vue的表单验证:VeeValidate
- Blazor的表单验证:EditForm
一、表单输入绑定
表单输入主要涉及前面章节的双向绑定,但不需要我们自定义,直接使用就行。如果已经掌握了“1.6章节双向绑定”,那这部分的知识点简直“洒洒水”。Vue的v-model指令,为所有原生的HTML组件做了一些特殊处理,不仅支持双向绑定,也支持check或radio的分组。而Blazor,对原生HTML并没有做特殊处理,所以实现起来比较麻烦(见下例)。对于Blazor,推荐直接使用内置的表单组件,不仅可以直接双向绑定,还支持验证。以下例子,为原始HTML标签的绑定。
//Vue //以下代码展示多行文本框、单行文本框、单行文本框-去空格、单行文本框-数字、复选框、多选框、单选框、单选选择器、多选选择器的基本使用 //多行文本框: 逻辑层值:{{textareaMsg}} //单行文本框: "text" v-model="inputMsg" placeholder="请输入" /> 逻辑层值:{{inputMsg}} //单行文本框-去空格: "text" v-model.trim="inputMsgTrim" placeholder="请输入" /> 逻辑层值:{{inputMsgTrim}} //单行文本框-数字: "number" v-model.number="inputNumber" placeholder="请输入" /> 逻辑层值:{{inputNumber}} //复选框: "checkbox" id="checkbox" v-model="isCheck" /> 逻辑层值:{{isCheck}} //多选框: "checkbox" id="vuecheck" value="vue" v-model="checkValue" /> "checkbox" id="blazorcheck" value="blazor" v-model="checkValue" /> 逻辑层值:{{checkValue}} //单选框: "radio" id="vueradio" value="vue" v-model="radioValue" /> "radio" id="blazorradio" value="blazor" v-model="radioValue" /> 逻辑层值:{{radioValue}} //单选选择器: <select v-model="oneSelected"> select> 逻辑层值:{{oneSelected}} //多选选择器: <select v-model="moreSelected" multiple> select> 逻辑层值:{{moreSelected}}
//Blazor //Blazor的@bind对check和rado的分组,并没有做出特殊处理class="content"> 多行文本框:逻辑层值:@textareaMsg
class="content"> 单行文本框: "inputMsg" @bind:event="oninput" />逻辑层值:@inputMsg
class="content"> 单行文本框-去空格: "InputTrimMsg" @bind:event="oninput" />逻辑层值:@InputTrimMsg
class="content"> 单行文本框-数字: "number" @bind="inputNumber" @bind:event="oninput" />逻辑层值:@inputNumber
class="content"> 复选框: "checkbox" id="isChecked" @bind="isChecked" />//多选框,无法使用@bind。通过双向绑定的属性和事件来实现【后面补充一种使用@bind的实现方式】逻辑层值:@(isChecked?"选中状态":"未选状态")
class="content"> 多选框: "checkbox" id="vuecheck" name="moreLikeCodes" value="@moreLikeCodes" @onchange=Vuecheck /> "checkbox" id="blazorcheck" name="moreLikeCodes" value="@moreLikeCodes" @onchange=Blazorcheck />//单选框,无法使用@bind。通过双向绑定的属性和事件来实现【后面补充一种使用@bind的实现方式】逻辑层值:@(String.Join(",", moreLikeCodes.ToArray()))
class="content"> 单选框: "radio" id="vueradio" name="oneLikeCode" value="@oneLikeCode" @onchange=@(()=>{oneLikeCode="vue";}) /> "radio" id="blazorradio" name="oneLikeCode" value="@oneLikeCode" @onchange=@(()=>{oneLikeCode="blazor";}) />逻辑层值:@oneLikeCode
class="content"> 单选选择器: <select @bind="singleSelected"> select>@code { private string textareaMsg = ""; private string inputMsg = ""; public int inputNumber { get; set; } //通过设置set,实现去除空格功能 private string inputTrimMsg = ""; public string InputTrimMsg { get { return inputTrimMsg; } set { inputTrimMsg = value.Trim(); } } private bool isChecked; //多选框 private List<string> moreLikeCodes = new List<string>(); private void Vuecheck(ChangeEventArgs e) { if (Convert.ToBoolean(e.Value)) { moreLikeCodes.Add("vue"); } else { moreLikeCodes.Remove("vue"); } } private void Blazorcheck(ChangeEventArgs e) { if (Convert.ToBoolean(e.Value)) { moreLikeCodes.Add("blazor"); } else { moreLikeCodes.Remove("blazor"); } } //单选框 private string? oneLikeCode; //单选下拉框 private string? singleSelected; }逻辑层值:@singleSelected
//Blazor //补充另外一种实现多选框的方式,直接用@bind指令 @if (selectedLikeCodes is not null) { foreach (var item in selectedLikeCodes) { "checkbox" @bind="@item.IsSelected" /> @item.Name }我喜欢的代码:
@foreach (var item in selectedLikeCodes.Where(c => c.IsSelected)) {@item.Name} } @code { private ListselectedLikeCodes = new List (); private List likeCodeItems = new List { new LikeCode{Name="vue",IsSelected=false}, new LikeCode{Name="blazor",IsSelected=false}, new LikeCode{Name="maui",IsSelected=false} }; protected override void OnInitialized() { selectedLikeCodes = likeCodeItems.Select(e => new LikeCode { Name = e.Name, IsSelected = e.IsSelected }).ToList(); } private class LikeCode { public string? Name; public bool IsSelected; } }
二、Vue的表单验证:VeeValidate
Vue没有内置表单验证功能,官方推荐使用第三方库VeeValidate。而Blazor,封装了一套内置表单组件,自带验证功能,我们主要学习这套组件的使用。本章节关于表单验证的知识点,均只涉及基本的使用,关于进一步的深入使用、理解、甚至定制扩展功能,我们将在进阶学习中继续展开。
1、VeeValidate的安装、组件式的简单使用
VeeValidate实现表单验证有两种方式,一种是组件式,主要使用和
(1)网络上搜索VeeValidate的安装使用,大多数会提示:①安装,npm install vee-validate;②在main.js中引入,import VeeValidate from ‘vee-validate’;③在main.js中安装插件,Vue.use( VeeValidate)或app.use( VeeValidate)。实际上,在Vue3,只要①就可以了。估计是Vue3引入组合式API之后,VeeValidate也是以组合式API的方式引入。如果是Vue2,可能还是需要三步来引入。
(2)完成①后,直接在组件中import就可以使用相关组件或API,以组件式为例:import { Field, Form, ErrorMessage } from 'vee-validate'
(3)VeeValidate官方推荐结合yup来使用。yup可以理解为验证函数的语法糖,如下例所示(使用组件方式)。yup需要另外安装,npm install yup;然后在组件中引入,import * as yup from ‘yup’。我们后面的案例,均使用更简单的验证方式yup。
//函数验证和yup验证方式的对比
//【特别说明一下】:以往我们使用HTML表单组件,都需要v-model逻辑层的响应式数据,但在VeeValidate里,你找不到了
////字段级验证 //表单级验证
2、VeeValidate的组合式API使用
VeeValidate起头的API主要有两个,useField和useForm。从字面就知道,一个是关于字段的,一个是关于表单的。
1)useField:const{ value, errorMessage } = useField('fieldName', yup.string().required().min(8))
①接受:字段name、字段级的验证方法、字段级初始值等入参
②export:字段value、错误信息errorMessage、字段元信息meta、值变化处理函数handleChange、字段重置resetField等一大堆API。使用对象解构的方式来接收,大多数解构出来的值,也是响应式。
2)useField:useForm:const{ handleSubmit, isSubmitting } = useForm()
①接受:表单级验证方法对象、表单级初始值对象等入参
②export:表单提交handleSubmit、提交状态isSubmitting、表单元信息meta等一大堆API。使用对象解构的方式来接收,大多数解构出来的值,也是响应式。
3)如上所述,VeeValidate的使用套路很简单,直来直去的三步走,入参-解构拿API-使用API
4)下面来个大例子,大多数API都有涉及和讲解,很全了哦!!!
class="content200">
表单所有字段值
{{values}}
表单所有错误信息
{{errors}}
三、Blazor的表单验证:EditForm
Blazor自带验证体系,使用起来非常方便,一般的验证功能都能实现,如果想实现更复杂的逻辑,也可以进一步深入。有几点需要说明:
1、需要使用Blazor自带的一整套组件,包括
2、验证的基本过程:
1)表单组件初始化后,会创建一个EditContext对象,这是表单的上下文,不仅以键值对
2)这个EditContext以CascadingValue联级的方式提供给表单组件使用
3)每次有数据更新时,触发验证,并创建一个新的EditContext,验证结果会保存到一个ValidationMessageStore
3、如果表单组件绑定了集合或复杂类型,将无法验证。这个时候有一个实验性的组件可以使用,
4、接下来和Vue一样,直接干一个实例!!!
class="container"> //EditForm的Model属性,可以直接绑定employee对象,这里绑定editContext的原因是为了拿到EditContext上下文 //提交表单的三种情况:OnValidSubmit-验证成功回调、OnInValidSubmit-验证失败回调、OnSubmit-无论成功或失败均回调 //OnValidSubmit和OnInValidSubmit可以一起使用@code { private Employee employee = new Employee(); private EditContext? editContext; protected override void OnInitialized() { editContext = new EditContext(employee); } private void MyValidSubmit() { Console.WriteLine("验证通过,提交表单"); } //表单绑定的对象,直接标注验证规定和错误信息,非常好用 //这个类还可以前后端共享 private class Employee { [Required(ErrorMessage = "姓名必填")] [MaxLength(20, ErrorMessage = "最长20字")] public string? Name { get; set; } = null; //姓名 [Required(ErrorMessage = "性别必填")] public Sex? Sex { get; set; } = null; //性别 [Required(ErrorMessage = "年龄必填")] [Range(18, 60, ErrorMessage = "只能填18-60岁")] public int Age { get; set; } //年龄 [Required] public Graduate Graduate { get; set; } = Graduate.Null;//学历 public bool IsMarriage { get; set; } //是否已婚 [DataType(DataType.Date)] public DateTime EntryDate { get; set; } //入职日期 [Required, MinLength(1, ErrorMessage = "最少选1个"), MaxLength(3, ErrorMessage = "最多选3个")] public Like[] Likes { get; set; } = new[] { Like.basketball }; //爱好 [MaxLength(300, ErrorMessage = "最长300字")] public string? Introduce { get; set; } //自我介绍 } //Employee对象用到的枚举类型 private enum Sex{ male,female } private enum Like{ football,basketball,swim,code } private enum Graduate{ Null,primary,middle,high,university } }"@editContext" OnValidSubmit="@MyValidSubmit"> //启动验证 //表单级验证信息的容器 class=content50> *姓名:"name" @bind-Value="employee.Name"> //字段级验证信息容器employee.Name) /> class="content50"> *性别:"employee.Sex"> "@Sex.male">male "@Sex.female">female class="content50"> *年龄:"employee.Age"> class="content50"> *学历:"employee.Graduate"> class="content50"> 是否已婚:"employee.IsMarriage"> class="content50"> 入职日期:"employee.EntryDate"> class="content100"> 爱好:"employee.Likes"> class="content100"> 自我介绍:"employee.Introduce">