需求:通过按钮的点击事件控制另一个输出框/按钮的点击

目录

第一章 接到需求

第二章 了解需求

第三章 解决需求 

第四章 优化代码

第五章 解决问题


第一章 接到需求

  • 最近开发的时候遇到这么一个事,技术经理是个全栈,已经把接口生成了,而且前端页面也写好了一个初稿,操作什么的功能基本上已经布局好了,如下:

经理说需求了:这里有两个按钮,一个是导入文件的,一个是导入机构的,你看看怎么把这按钮功能实现,把excel文件导入进去,后台的接口已经写好了 

第二章 了解需求

  • 然后小编接到需求了,clone下代码,根据路由找到对应的页面代码(注释的部分是小编已经写好的代码):

  •  发现这里就是两个按钮,然后设置了权限一些其他配置。
  • (注意事项:我们很多人有的时候为了语义化一些特别容易出现一个问题:就是会用到关键字,比如小编一开始看这个代码的时候,上面写的是@click="import(scope.row.id)",好家伙,不细看不知道,代码一跑吓一跳,直接控制台报错,一定要留意,import是关键字,我们不要直接定义!!!语义化命名不要命名到关键字!!!
  • 好了,接下来进入正题:当我们拿到这么一个需求,首先我们分析一下,很明显,我们拿到的需求是一个上传文件的功能实现,平常我们上传文件很多时候会用到element、antd等等一些框架类的东西来实现这么一个功能。那么问题来了,我们这里就只有按钮,样式、布局都确定了,而且不管我们怎么点击,都没反应。那么接下来我们考虑的是不是给按钮添加点击事件 -> 调出本地文件管理器 -> 点击我们需要上传的文件 -> 上传成功拿到文件的二进制流 -> 准备上传的参数 -> 像后端发送请求 -> 后端返回成功/失败的数据 -> 前端拿到数据进行处理,那么难点在哪呢:一个按钮,怎么能调出本地的文件管理器呢,又怎么知道我们点击文件上传了呢,对于用很多组件的我们来说可能就麻烦了,去找组件啥啥啥,但是小编觉得,是的,组件或许能帮我们实现这么个需求,但是我们难道没有别的方法了吗?
  • 原生标签:input!!!小编回忆,最开始学习html的时候有个标签input,小编也不绕圈了,设置type="file"就是文件上传的按钮!!

  • 回忆一下,看如下文档:

HTML input type 属性 | 菜鸟教程

第三章 解决需求 

  • 好了,用到的工具有了,现在的问题在于如何解决我们利用导入的按钮操作文件上传的按钮?
  • 思路:小编为按钮与input都绑定唯一识别的ref(vue)/id(正常的html页面)以及click点击事件,原生js会告诉我们,当我们绑定id时,获取到DOM之后,我们能通过DOM.click获取到DOM上绑定的点击事件。问题解决!
  • 大家根据小编的代码理解逻辑:(小编会逐步解释的) 

html: 

// 这里是element-ui的button组件
<el-button v-if="hasPermission('book:book:import')" // 通过权限控制图标显示隐藏(可忽略)type="text" //button的type(可忽略)icon="el-icon-import" // 图标类名(可忽略)size="small" // 尺寸@click="toImportBookList(scope.row.id)"> // 按钮的点击事件,传的参数是该行数据的id导入</el-button>
// 原生的input
<input type="file" // 上传文件的类型accept=".xls,.xlsx" // 限制上传的文件格式:ref="`upload-book-list-file-${scope.row.id}`"  // 唯一识别的ref,利用id使得渲染时ref不重名style="display: block" // 控制该标签的显示隐藏@click="importBookList(scope.row.id)"> // 该标签的点击事件

js:(注意一定要理解思路,而不是直接拷贝代码)

export default {methods: { // vue:方法toImportBookList (id) { // 按钮的点击事件const bookListFileUplodDom = this.$refs[`upload-book-list-file-${id}`] // 通过$refs获取对应的input标签bookListFileUplodDom.click() // 注意这句代码,他就是通过dom调用自身的点击事件},importBookList (id) { // input标签的点击事件const _this = thisconst bookListFileUplodDom = this.$refs[`upload-book-list-file-${id}`] // 通过$refs获取input标签bookListFileUplodDom.addEventListener('change', function (e) { // input标签监听事件,当input发生变化时说明文件要么上传了,要么删除了,上传成功执行如下代码const file = bookListFileUplodDom.files[0] // 该方法只针对input、type="file"或者图片,才能使用他获取到file的二进制流const formBody = new FormData() // 这里的formData小编就不多说了,已经用到很多次了,小编会有单独的详细的文章做讲解formBody.append('file', file)formBody.append('id', id)this.loading = true // 添加加载中(可忽略)bookService.importBook(formBody).then(({data}) => { // 这里是发送请求系列信息,仅供参考this.$message.success({ // 请求成功后返回信息dangerouslyUseHTMLString: true,message: data})this.refreshList() // 刷新列表}).catch(err => { // 出错了则捕获错误this.loading = false // 隐藏加载中console.log('出错了', err)})}, false)}}
}

第四章 优化代码

  • 使用e.stopPropagation()

阻止事件冒泡,使用addEventListener,三个参数,第三个参数小编设置了false,表示的是事件冒泡,由里向外触发,子元素的点击事件触发之后,之后还会触发父元素的点击事件,从而导致我们点击事件执行到不需要执行的事件,触发顺序:children -> parent -> body,添加e.stopPropagation()就只会执行我们点击的标签的点击事件。代码如下:

bookListFileUplodDom.addEventListener('change', function (e) {e.stopPropagation() // 阻止冒泡事件(注意该方法写在代码前面)……(其余代码逻辑)
}, false)
  • addEventListener我们注册的监听'change'函数有两种情况:当上传文件成功时,input变化了,会执行代码,然后向发送请求,当然,当我们删除文件时,文件都为空了,还需要执行代码,向后端发请求吗?所以需要我们判断一下,当删除文件时,不执行代码,不向后端发送请求

 

 通过输出可以看到,删除文件时,file拿到的值是undefined,那么我们就能通过判断来解决该问题了,代码如下:

bookListFileUplodDom.addEventListener('change', function (e) {e.stopPropagation() // 阻止冒泡事件(注意该方法写在代码前面)const file = bookListFileUplodDom.files[0]if(file){ // 只有当file有数据时才执行如下逻辑……(其余代码逻辑)}
}, false)
  •  addEventListener注册了还需要removeEventListener移除事件,如何removeEventListener移除呢,在哪移除呢,解决方法在下一章节

第五章 解决问题

  • 查看问题,不如不添加removeEventListener的效果,当我们执行多次导入时,也就相当于注册了很多个addEventListener('change',function(e){})事件,就会造成当我们只执行一次有效操作时,多个监听开始执行,导致最终前端会发送多个相同的请求

 

  • (这里直接给出小编的最终解决完成的源代码,如果大家进一步知道原理,小编会在下一篇文章中说明原因,做详细的解释!)
  • 原理看该文章

js基础:addEventListener与removeEventListener使用时,涉及的问题(包括事件捕获、冒泡,removeEventListener不生效问题)-CSDN博客

<script>let bookListHandler = null // 定义一个自变量的等待赋值(移除监听函数使用)export default {methods: {toImportBookList (id) {const bookListFileUplodDom = this.$refs[`upload-book-list-file-${id}`]bookListFileUplodDom.removeEventListener('change', bookListHandler, false) // 每次调用函数执行移除上一次的添加的监听bookListFileUplodDom.click()},importBookList (id) {const _this = thisconst bookListFileUplodDom = this.$refs[`upload-book-list-file-${id}`]console.log('bookListFileUplodDom', bookListFileUplodDom)bookListHandler = function (e) { // 将执行的监听函数赋值e.stopPropagation()_this.getBookList(id, bookListFileUplodDom)}bookListFileUplodDom.addEventListener('change', bookListHandler, false) // 添加监听事件},getBookList (id, bookListFileUplodDom) {const file = bookListFileUplodDom.files[0]console.log('file', file)if (file) {const formBody = new FormData()formBody.append('file', file)formBody.append('id', id)this.loading = truebookService.importBook(formBody).then(({data}) => {this.$message.success({dangerouslyUseHTMLString: true,message: data})this.refreshList()}).catch(err => {this.loading = falseconsole.log('出错了', err)})}},}
}
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/236774.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

tp6使用Smarty模板引擎

安装Smarty模板引擎&#xff1a;首先&#xff0c;确保你已经安装了Smarty模板引擎。你可以通过Composer进行安装&#xff0c;或者手动下载并解压Smarty的库文件。 配置TP6框架&#xff1a;在TP6的配置文件中&#xff0c;你需要进行一些配置来启用Smarty模板引擎。通常&#xf…

【已解决】taos时序数据库3.0版本,怎么按照时间分组?

taos数据库中按照时间分组&#xff0c;在2.4版本时候可以直接使用INTERVAL(time_unit)来查询。例如 前面可以直接添加_ts的。但是在3.0版本之后&#xff0c;如果直接使用的话&#xff0c;只会返回count&#xff1a; 没有前面的时间。那么在3.0版本时候&#xff0c;怎么修改呢&a…

在mt4上怎么查看CHFJPY品种的合约细则?

在MetaTrader 4 (MT4) 上查看CHFJPY品种的合约细则的方法如下&#xff1a; FXCM福汇官方个人注册登录流程 1.打开MT4软件并登录到您的交易账户。 2.在MT4界面的"市场观察"窗格中&#xff0c;找到并右键单击"CHFJPY"货币对。如果您无法找到"市场观察…

【华为OD题库-102】排队游戏-java

题目 新来的老师给班里的同学排一个队。每个学生有一个能力值。一些学生是刺头&#xff0c;不会听老师的话&#xff0c;自己选位置&#xff0c;非刺头同学在剩下的位置按照能力值从小到大排。对于非刺头同学&#xff0c;如果发现他前面有能力值比自己高的同学&#xff0c;他不满…

时间是如何定义的

每年365天&#xff0c;每天24小时&#xff0c;每小时60分钟&#xff0c;每分钟60s&#xff0c;这是我们习以为常的时间计量单位&#xff0c;那么在继续往下&#xff0c;1s是多少&#xff1f;几时几刻、几点几分是如何确定的&#xff1f;带着这些问题&#xff0c;展开本文。 1、…

常见分布的分布列/概率密度、分布函数、期望、方差、特征函数

0-1分布 二项分布 泊松分布 几何分布 均匀分布 正态分布 指数分布 伽马分布 卡方分布

2023.12.18 关于 CentOS7 安装 Redis5

目录 安装步骤 创建符号连接 修改配置文件 启动 redis 服务器 停止 redis 服务器 安装步骤 CentOS7 的 yum 仓库中&#xff0c;redis 的默认版本为 3 系列为了 能让 CentOS7 安装上 Redis5&#xff0c;此处我们需要安装额外软件源 1、安装额外软件源 yum install cento…

腾讯云消息队列11月产品月报 | RocketMQ 5.x 国际站上线

2023年 11月动态 消息队列 RocketMQ 版 1、5.x 形态国际站上线 国际站上线 5.x 集群全系列&#xff0c;第一批先开放新加坡和硅谷地域。 控制台链接&#xff1a;https://console.tencentcloud.com/trocketmq 2、 无感迁移能力 支持用户白屏化操作&#xff0c;将自建的 Roc…

提前预判和确认再做 现货白银投资的两种思路

在现货白银投资中&#xff0c;对于交易的步骤长期有两种看法。一种是提前预判行情并提前布局。另外一种是等待行情启动再做布局。这种两种方法要怎么选呢&#xff1f;笔者将从自己的角度出发&#xff0c;对这个问题进行讨论。 我们来看一下前一种的投资者&#xff0c;他们喜欢提…

标准库中的string类(中)+仅仅反转字母+字符串中的第一个唯一字符+字符串相加——“C++”“Leetcode每日一题”

各位CSDN的uu们好呀&#xff0c;今天&#xff0c;继续小雅兰西嘎嘎的学习&#xff0c;标准库中的string类&#xff0c;下面&#xff0c;让我们一起进入西嘎嘎string的世界吧&#xff01;&#xff01;&#xff01; string类的常用接口说明 Leetcode每日一题 string类的常用接口…

pip 常用指令 pip install 命令用法介绍

pip install 是一个 Python 包管理器命令&#xff0c;用于安装 Python 包。pip 是 Python 的一个重要工具&#xff0c;可以用来安装、升级和卸载 Python 包。 pip install 命令的一些常见参数有 -r&#xff1a;从一个需求文件中安装所有的包。-U 或 --upgrade&#xff1a;升级…

该目录不在项目的文件列表中,项目必须列出所有文件,或使用“include“模式

vue3 构建项目配置路由 router 的时候,因对某个类重命名后抛出如下异常 该目录不在项目的文件列表中,项目必须列出所有文件,或使用"include"模式 解决办法 前往 tsconfig.node.json 文件中对 include 新增 scr/icons/* 即可 {"extends": "./tsconfi…

TrustZone之问答

以下问题有助于测试您的知识。 在Arm架构中&#xff0c;安全状态和物理地址空间分别是什么&#xff1f; 在Arm架构中&#xff0c;安全状态分为安全状态和非安全状态。物理地址空间分为安全物理地址空间和非安全物理地址空间。 在每个异常级别中&#xff0c;是什么确定处理器处于…

鸿蒙开发基本概念

1、开发准备 1.1、UI框架 HarmonyOS提供了一套UI开发框架&#xff0c;即方舟开发框架&#xff08;ArkUI框架&#xff09;。方舟开发框架可为开发者提供应用UI开发所必需的能力&#xff0c;比如多种组件、布局计算、动画能力、UI交互、绘制等。 方舟开发框架针对不同目的和技术…

基于MLP完成CIFAR-10数据集和UCI wine数据集的分类

基于MLP完成CIFAR-10数据集和UCI wine数据集的分类&#xff0c;使用到了sklearn和tensorflow&#xff0c;并对图片分类进行了数据可视化展示 数据集介绍 UCI wine数据集&#xff1a; http://archive.ics.uci.edu/dataset/109/wine 这些数据是对意大利同一地区种植的葡萄酒进…

[SWPUCTF 2021 新生赛]jicao

首先打开环境 代码审计&#xff0c;他这儿需要进行GET传参和POST传参&#xff0c;需要进行POST请求 变量idwllmNB&#xff0c;进行GET请求变量json里需要含参数x以及jsonwllm 构造 得到flag

在线更换Proxmox VE超融合集群Ceph OSD磁盘

因为资源紧张的原因&#xff0c;担心一旦关机&#xff0c;虚拟机因为没有空闲的资源而被冻结&#xff0c;以致于不能漂移&#xff0c;导致部分服务停止&#xff0c;只好让机房帮忙热插拔。 幸运的是&#xff0c;插上去能够被系统所识别&#xff08;/dev/sdf就是新插入的硬盘&am…

ip静态好还是dhcp好?

选择使用静态 IP 还是 DHCP&#xff08;动态主机配置协议&#xff09;取决于您的网络需求和环境。下面是它们的一些特点和适用场景&#xff1a; 静态 IP&#xff1a; 固定的 IP 地址&#xff1a;静态 IP 是手动配置在设备上的固定 IP 地址&#xff0c;不会随时间或网络变化而改…

指针(3)计算最长的字符串长度(本题要求实现一个函数,用于计算有n个元素的指针数组s中最长的字符串的长度)以及就题讲解malloc函数

题目要求 本题要求实现一个函数&#xff0c;用于计算有n个元素的指针数组s中最长的字符串的长度。 函数接口定义&#xff1a; int max_len( char *s[], int n ); 其中n个字符串存储在s[]中&#xff0c;函数max_len应返回其中最长字符串的长度。 裁判测试程序样例&#xff…

Redis多路复用在不同操作系统的性能

Redis多路复用 在redis中在不同系统中会使用不同的模型&#xff0c;但是多路复用的原理还是一个进程或者线程可以同时处理多个连接&#xff0c;不需要为每个连接都创建一个单独的线程或者进程。不同的多路复用机制在具体实现有一些差异&#xff0c;但是核心思想还是单个进程或…