热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Vue模仿ElementUI的form表单实例代码

这篇文章主要给大家介绍了关于Vue模仿ElementUI的form表单的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

实现要求

模仿 ElementUI 的表单,分为四层结构:index 组件、Form 表单组件、FormItem 表单项组件、Input 和 CheckBox 组件,具体分工如下:

index 组件:

  • 实现:分别引入 Form 组件、FormItem 组件、Input 组件,实现组装;

Form 表单组件:

  • 实现:预留插槽、管理数据模型 model、自定义校验规则 rules、全局校验方法 validate;

FormItem 表单项组件:

  • 实现:预留插槽、显示 label 标签、执行数据校验、显示校验结果;

Input 和 CheckBox 组件:

  • 实现:绑定数据模型 v-model、通知 FormItem 组件执行校验;

Input 组件

具体实现如下:

1、自定义组件要实现 v-model 必须实现 :value 和 @input。

2、当输入框中的数据发生变化时,通知父组件执行校验。

3、当 Input 组件绑定的 type 类型为 password 时,在组件内部使用 v-bind="$attrs" 获取 props 之外的内容。

4、设置 inheritAttrs 为 false, 从而避免顶层容器继承属性。

Input 组件实现:






注意:代码中使用 this.$parent 派发事件,这种写法不健壮,当 Input 组件和 FormItem 组件之间隔代时会出现问题。具体解决方式见文章尾部代码优化部分。

CheckBox 组件

1、自定义实现 checkBox 的双向数据绑定,和 input 大同小异,必须实现 :checked 和 @change。

CheckBox 组件实现:





FormItem 组件

具体实现如下:

1、给 Input 组件或者 CheckBox 组件预留插槽。

2、如果用户在组件上设置 label 属性,要展示 label 标签。

3、监听校验事件,并执行校验(使用 async-validator 插件进行校验)。

4、如果不符合校验规则,需要显示校验结果。

在开发的过程中,我们需要思考几个问题:

1、在组件内部,如何得到需要校验的数据和校验规则?

2、在 Form 表单中会有多个菜单项,如:用户名、密码、邮箱...等等,那么 FormItem 组件是如何得知现在校验的是哪个菜单呢?

FormItem 组件实现:






我们先回答一下上面提出的两个问题,此处会涉及到组件之间传值,可以参考之前的文章《组件传值、通讯》:
首先表单的数据和校验规则是定义在 index 组件内部,并且挂载在 Form 组件上,表单的校验项发生在 FormItem 组件中,先在 Form 组件内部通过 props 接受到传递的数据,然后通过 provide/inject 的方式在 FormItem 组件中传递给后代组件。

我们日常在用 ElementUI 的表单校验是会发现,在每一个需要校验的表单上会设置一个 prop 属性,并且属性值和绑定的数据一致。此处的用途是为了能够在 FormItem 组件中执行校验时获取相对的校验规则和数据对象。

在 FormItem 组件中通过使用 inject 获取注入的 Form 实例,和 prop 属性组合使用,可以获取到表单数据和校验规则。

// 1、获取数据
const values = this.formModel.model[this.prop];

// 2、获取校验规则
const rules = this.formModel.rules[this.prop];

使用 async-validator 插件实例化一个 schema 对象,用来执行校验,schema.validate 需要传递两个参数,参数1是当前需要校验的字段和相对应的 rules 组成的键值对对象,参数2是一个 callback 函数,用来获取错误信息(是一个数组)。validate 方法返回的是一个 Promise

注意:此组件的 validate 方法中,最后使用 return 的目的是为了在 Form 组件中执行全局校验使用。

Form 组件

具体实现如下:

1、给 FormItem 组件预留插槽。

2、传递 Form 实例给后代,比如 FormItem 用来获取校验的数据和规则。

3、执行全局校验

Form 组件实现:






我们在 Form 组件中使用 provide 注入当前组件对象,方便后续子孙代获取数据/方法使用。

执行全局校验的时候,先使用 filter 过滤掉不需要校验的组件(我们在 FormItem 组件上设置的 prop 属性,只要有此属性,就是需要校验的),然后分别执行组件中的 validate 方法(如果在 FormItem 组件中不使用 return 数据,最后获取到的全都是 undefined),返回的是一个若干  Promise 数组。

简单介绍一个 Promise.all() 方法:

Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 那个输入的所有promise的resolve回调的结果是一个数组。这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。

index 组件

定义模型数据、校验规则等等,分别引入 Form 组件、FormItem 组件、Input 组件,实现组装。

index 组件实现:






当我们点击登录按钮时,会执行全局校验方法,我们可以使用 this.$refs.xxx 获取 DOM 元素和组件实例。

在上面我们还留了一个小尾巴~,就是在 Input 组件中通知父组件执行校验,目前使用的是 this.$parent.$emit(),这样写有一个弊端,就是当 Input 组件和 FormItem 组件之后隔代的时候,再使用 this.$parent 获取不到 FormItem 组件。
我们可以封装一个 dispatch 方法,主要实现向上循环查找父元素并且派发事件,代码实现如下:

dispatch(eventName, data) {
 let parent = this.$parent;
 // 查找父元素
 while (parent) {
 // 父元素用$emit触发
 parent.$emit(eventName, data);
 // 递归查找父元素
 parent = parent.$parent;
 }
}

该方法可以借用 mixins 引入使用:mixins/emmiters.js

export default {
 methods: {
 dispatch(eventName, data) {
 let parent = this.$parent;
 // 查找父元素
 while (parent) {
 // 父元素用$emit触发
 parent.$emit(eventName, data);
 // 递归查找父元素
 parent = parent.$parent;
 }
 }
 }
};

修改 Input 组件:






总结

到此这篇关于Vue模仿ElementUI的form表单的文章就介绍到这了,更多相关Vue模仿ElementUI form表单内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!


推荐阅读
  • 深入解析Spring Cloud Ribbon负载均衡机制
    本文详细介绍了Spring Cloud中的Ribbon组件如何实现服务调用的负载均衡。通过分析其工作原理、源码结构及配置方式,帮助读者理解Ribbon在分布式系统中的重要作用。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 实体映射最强工具类:MapStruct真香 ... [详细]
  • 本文探讨了在 ASP.NET MVC 5 中实现松耦合组件的方法。通过分离关注点,应用程序的各个组件可以更加独立且易于维护和测试。文中详细介绍了依赖项注入(DI)及其在实现松耦合中的作用。 ... [详细]
  • Startup 类配置服务和应用的请求管道。Startup类ASP.NETCore应用使用 Startup 类,按照约定命名为 Startup。 Startup 类:可选择性地包括 ... [详细]
  • 网易严选Java开发面试:MySQL索引深度解析
    本文详细记录了网易严选Java开发岗位的面试经验,特别针对MySQL索引相关的技术问题进行了深入探讨。通过本文,读者可以了解面试官常问的索引问题及其背后的原理。 ... [详细]
  • 本文将深入探讨如何在不依赖第三方库的情况下,使用 React 处理表单输入和验证。我们将介绍一种高效且灵活的方法,涵盖表单提交、输入验证及错误处理等关键功能。 ... [详细]
  • 探索电路与系统的起源与发展
    本文回顾了电路与系统的发展历程,从电的早期发现到现代电子器件的应用。文章不仅涵盖了基础理论和关键发明,还探讨了这一学科对计算机、人工智能及物联网等领域的深远影响。 ... [详细]
  • 科研单位信息系统中的DevOps实践与优化
    本文探讨了某科研单位通过引入云原生平台实现DevOps开发和运维一体化,显著提升了项目交付效率和产品质量。详细介绍了如何在实际项目中应用DevOps理念,解决了传统开发模式下的诸多痛点。 ... [详细]
  • Docker的安全基准
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 深入理解 .NET 中的中间件
    中间件是插入到应用程序请求处理管道中的组件,用于处理传入的HTTP请求和响应。它在ASP.NET Core中扮演着至关重要的角色,能够灵活地扩展和自定义应用程序的行为。 ... [详细]
  • 本文介绍如何在Spring Boot项目中集成Redis,并通过具体案例展示其配置和使用方法。包括添加依赖、配置连接信息、自定义序列化方式以及实现仓储接口。 ... [详细]
  • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
  • 在 Android 开发中,通过 Intent 启动 Activity 或 Service 时,可以使用 putExtra 方法传递数据。接收方可以通过 getIntent().getExtras() 获取这些数据。本文将介绍如何使用 RoboGuice 框架简化这一过程,特别是 @InjectExtra 注解的使用。 ... [详细]
  • 云函数与数据库API实现增删查改的对比
    本文将深入探讨使用云函数和数据库API实现数据操作(增删查改)的不同方法,通过详细的代码示例帮助读者更好地理解和掌握这些技术。文章不仅提供代码实现,还解释了每种方法的特点和适用场景。 ... [详细]
author-avatar
灰常奈-ping__
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有