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

相关文章

部署Vue项目到服务器后404错误的原因及解决方案

《部署Vue项目到服务器后404错误的原因及解决方案》文章介绍了Vue项目部署步骤以及404错误的解决方案,部署步骤包括构建项目、上传文件、配置Web服务器、重启Nginx和访问域名,404错误通常是... 目录一、vue项目部署步骤二、404错误原因及解决方案错误场景原因分析解决方案一、Vue项目部署步骤

Java调用DeepSeek API的最佳实践及详细代码示例

《Java调用DeepSeekAPI的最佳实践及详细代码示例》:本文主要介绍如何使用Java调用DeepSeekAPI,包括获取API密钥、添加HTTP客户端依赖、创建HTTP请求、处理响应、... 目录1. 获取API密钥2. 添加HTTP客户端依赖3. 创建HTTP请求4. 处理响应5. 错误处理6.

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

golang内存对齐的项目实践

《golang内存对齐的项目实践》本文主要介绍了golang内存对齐的项目实践,内存对齐不仅有助于提高内存访问效率,还确保了与硬件接口的兼容性,是Go语言编程中不可忽视的重要优化手段,下面就来介绍一下... 目录一、结构体中的字段顺序与内存对齐二、内存对齐的原理与规则三、调整结构体字段顺序优化内存对齐四、内

CSS弹性布局常用设置方式

《CSS弹性布局常用设置方式》文章总结了CSS布局与样式的常用属性和技巧,包括视口单位、弹性盒子布局、浮动元素、背景和边框样式、文本和阴影效果、溢出隐藏、定位以及背景渐变等,通过这些技巧,可以实现复杂... 一、单位元素vm 1vm 为视口的1%vh 视口高的1%vmin 参照长边vmax 参照长边re

CSS3中使用flex和grid实现等高元素布局的示例代码

《CSS3中使用flex和grid实现等高元素布局的示例代码》:本文主要介绍了使用CSS3中的Flexbox和Grid布局实现等高元素布局的方法,通过简单的两列实现、每行放置3列以及全部代码的展示,展示了这两种布局方式的实现细节和效果,详细内容请阅读本文,希望能对你有所帮助... 过往的实现方法是使用浮动加

css渐变色背景|<gradient示例详解

《css渐变色背景|<gradient示例详解》CSS渐变是一种从一种颜色平滑过渡到另一种颜色的效果,可以作为元素的背景,它包括线性渐变、径向渐变和锥形渐变,本文介绍css渐变色背景|<gradien... 使用渐变色作为背景可以直接将渐China编程变色用作元素的背景,可以看做是一种特殊的背景图片。(是作为背

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

python实现简易SSL的项目实践

《python实现简易SSL的项目实践》本文主要介绍了python实现简易SSL的项目实践,包括CA.py、server.py和client.py三个模块,文中通过示例代码介绍的非常详细,对大家的学习... 目录运行环境运行前准备程序实现与流程说明运行截图代码CA.pyclient.pyserver.py参