vue2实践:第一个非正规的自定义组件-动态表单对话框

本文主要是介绍vue2实践:第一个非正规的自定义组件-动态表单对话框,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

vue一个很重要的概念就是组件,作为一个没有经历过前几代前端开发的我来说,不太能理解它所带来的“进步”,但是,将它与后端c++、java类比,我感觉,组件就像是这些语言中的类和对象的概念,通过封装好的组件(类),可以通过挂载的方式,非常方便的调用其提供的功能,而不必重新写一遍实现逻辑。

我们常用的element UI就是由饿了么所提供的组件库,但是在项目开发中,我们可能还需要额外地定义一些组件来使用,就像java中我们会使用很多很多原生库和三方库以外,也要自己定义许多许多的实体类和工具类来满足项目需要。

需求

之前,使用el-table实现了一个用户可以自己添加删除行并填写内容的动态表格(后面补)。缺点是:用户输入了多行数据,在最后保存的时候才会做数据校验和提示。感觉不太符合现在表单设计的通用标准,所以,再次遇到这种需求时,我改成了用el-form来实现,让它能够实时校验用户的输入。与一般的el-form的不同在于,这次需要使用v-for遍历一个数组来使表单的row根据数组的长度来动态变化,其余与前一篇动态表格相似。

<el-form-item label="人员" prop="people"><el-row v-for="(row, index) in form.people" :key="index"><el-col :span="10"><el-form-item:prop="`people[${index}].nickName`":rules="[{required: true,message: '人员姓名不能为空',trigger: 'blur'}]"><el-input v-model.trim="form.people[index].nickName" placeholder="请输入人员姓名"/></el-form-item></el-col>....</el-row>...
</el-form-item>

只是,使用el-form,就可以使用它提供的rules了。具体实现及表单校验方式参见vue2表单校验:el-form表单绑定数组并使用rules进行校验_vue2 rules-CSDN博客和vue2表单校验:添加自定义el-form表单校验规则-CSDN博客

因为是第二次遇到这种需求,为了以后能够不再重复的写这部分代码逻辑,我考虑将它写成一个组件,直接调用。因为这两个需求都是对话框,所以,我写了一个对话框组件,本篇着重记录组件的实现

组件的实现

一、定义输入

就像我们定义一个类时,需要有set/get,定义一个方法,需要有入参和可能的返回值return一样,一个组件,也需要有输入项来支撑它的数据初始化,等它的操作完成,需要通知它的父组件来进行数据处理,比如,刷新列表等。所以,我们先根据实际的业务需求,定义它的输入输出项。

我这里是添加人员,根据所添加人员的角色的不同,对话框的title要发生变化,所以,至少初始化时需要传入角色、或者说title信息,另外,保存时也需要知道公司信息等。因为是对话框,我打算在父组件调用对话框,即显示(show)的时候,接收这些入参。

1、template:将控件放置在一个el-dialog中

  <el-dialog:title="dialogTitle"class="dialogCls":visible.sync="dlgVisible":close-on-click-modal="false"ref="_dialog_"v-dialogDragwidth="700px":before-close="onCancel"append-to-body>
。。。。

2、为该组件定义一个名字,以供从其它组件中调用。

export default {name: 'createAccountDlg',props:...
....
}

3、data中定义一个dialogOptions,用来接收入参

dialogOptions:{companyId: null,...//其它参数    
},

4、method中提供show方法,供父组件触发该对话框显示 

show: function (options) {//备份原始默认选项用于关闭时恢复原状this.origDialogOptions = options;//扩展复制调用选项到dialogOptionslet _dialogOptions_ = options || this.defaultDialogOptions;this.dialogOptions = $.extend(this.defaultDialogOptions, JSON.parse(JSON.stringify(_dialogOptions_)));//显示对话框this.dlgVisible = true;
},

5、在computed中定义属性dlgTitle,以在接收到参数后,更新对话框标题

computed: {//对话框标题dialogTitle(){if(this.dlgVisible) {return `添加${this.dialogOptions.role.roleName}`;}},
}

 6、内部添加删除行等的代码实现,跟之前一样,这里不再赘述

二、定义输出

等用户添加完,点击保存时,需要将所有数据保存到数据库中,而且,还要通知它的父组件刷新人员列表,这部分,通过$emit向父组件来发送一个事件,由父组件响应这个事件,并做对应的操作。(这里只是为了展示在保存后使用$emit发射事件的过程,有异步问题带来的bug,下一篇会说)

onSave(){this.$refs.form.validate(valid => {if (valid) {this.addUsrs();  //保存账号this.$emit("accountCreated"); //通知父组件保存完成,这里有异步问题this.dlgVisible = false;   //关闭对话框this.reset();   //重置入参}});
},

至此,组件的定义完成,主要包括入参处理、内部逻辑,以及结束时的通知事件$emit。如有需要,emit可携带更多参数传递给父组件:

this.$emit("eventName",{param1:param1Value, param2:param2Value})

组件的使用

一、挂载组件

需要先挂载这个组件,就像需要先加载第三方包一样。在整个项目的main.js中,挂载全局组件:

Vue.component('createAccountDlg', createAccountDlg)

二、 父组件中通过点击一个Button来触发

<el-button icon="el-icon-plus" type="primary" plain @click="createAccount">新增账号</el-button>createAccount(){let options = {//初始化参数companyId: this.from.companyId,              role:this.role}this.$refs.createAccountDlg.show(options);
},

三、组件执行结束,父组件收到accountCreated时的回调函数 

<create-account-dlg ref="createAccountDlg" @accountCreated="onAccountCreated"></create-account-dlg>onAccountCreated(){this.updateUserDataTable();
}

补充

prop

本文之所以叫非正规的自定义组件,是因为我觉得标准的组件定义中,入参应该通过prop来定义,如下:

props: {dlgTitle: {type: String,default: "创建人员"//required: true//还可以添加其它的类似于el-form rules中的校验逻辑},        
},

 这样在调用的时候,就像我们使用标准的element ui控件一样,要给出比如dlgTitle这个属性,替代在show中所给出的参数。(未实现,仅推测)

<create-account-dlg ref="createAccountDlg" dlgTitle="项目经理" @accountCreated="onAccountCreated"></create-account-dlg>

$emit:

看到很多人对emit的解释是:子组件通过$emit的方式,调用父组件中的事件,一直很难理解。在我的概念中,总觉得“调用”该通过名称去调用,而这里

//子组件中emit事件
this.$emit("accountCreated");//父组件中的响应
<create-account-dlg ref="createAccountDlg" @accountCreated="onAccountCreated"></create-account-dlg>

父组件调用时,用@,表示on event,也就是当父组件收到“accountCreated”这个事件时的响应是由“onAccountCreated”函数来完成的。这里,父组件仅仅是在监听“accountCreated”这个用户自定义的事件,就像监听原生的click事件一样,监听到了,便根据后面的函数,进行逻辑处理,并不关心这个事件是由谁发出的。

这种方式,我觉得更好理解父子间的数据传递逻辑。否则,父组件通过prop传递数据给子组件,子组件又调用父组件的方法,感觉有点混乱。

这篇关于vue2实践:第一个非正规的自定义组件-动态表单对话框的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1147931

相关文章

一文详解SpringBoot中控制器的动态注册与卸载

《一文详解SpringBoot中控制器的动态注册与卸载》在项目开发中,通过动态注册和卸载控制器功能,可以根据业务场景和项目需要实现功能的动态增加、删除,提高系统的灵活性和可扩展性,下面我们就来看看Sp... 目录项目结构1. 创建 Spring Boot 启动类2. 创建一个测试控制器3. 创建动态控制器注

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()

Spring Boot @RestControllerAdvice全局异常处理最佳实践

《SpringBoot@RestControllerAdvice全局异常处理最佳实践》本文详解SpringBoot中通过@RestControllerAdvice实现全局异常处理,强调代码复用、统... 目录前言一、为什么要使用全局异常处理?二、核心注解解析1. @RestControllerAdvice2

Spring事务传播机制最佳实践

《Spring事务传播机制最佳实践》Spring的事务传播机制为我们提供了优雅的解决方案,本文将带您深入理解这一机制,掌握不同场景下的最佳实践,感兴趣的朋友一起看看吧... 目录1. 什么是事务传播行为2. Spring支持的七种事务传播行为2.1 REQUIRED(默认)2.2 SUPPORTS2

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

MySQL 中 ROW_NUMBER() 函数最佳实践

《MySQL中ROW_NUMBER()函数最佳实践》MySQL中ROW_NUMBER()函数,作为窗口函数为每行分配唯一连续序号,区别于RANK()和DENSE_RANK(),特别适合分页、去重... 目录mysql 中 ROW_NUMBER() 函数详解一、基础语法二、核心特点三、典型应用场景1. 数据分

springboot如何通过http动态操作xxl-job任务

《springboot如何通过http动态操作xxl-job任务》:本文主要介绍springboot如何通过http动态操作xxl-job任务的问题,具有很好的参考价值,希望对大家有所帮助,如有错... 目录springboot通过http动态操作xxl-job任务一、maven依赖二、配置文件三、xxl-

深度解析Spring AOP @Aspect 原理、实战与最佳实践教程

《深度解析SpringAOP@Aspect原理、实战与最佳实践教程》文章系统讲解了SpringAOP核心概念、实现方式及原理,涵盖横切关注点分离、代理机制(JDK/CGLIB)、切入点类型、性能... 目录1. @ASPect 核心概念1.1 AOP 编程范式1.2 @Aspect 关键特性2. 完整代码实

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码