news 2026/3/6 23:54:15

Vue3文件上传使用@click.stop解决多次触发(事件冒泡)的问题

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue3文件上传使用@click.stop解决多次触发(事件冒泡)的问题

关键代码:

// 触发文件选择 const triggerFileSelect = (event?: Event) => { console.log("触发文件选择"); console.log("事件目标:", event?.target); console.log("当前目标:", event?.currentTarget); console.log("事件路径:", event?.composedPath()); if (fileInputRef.value) { fileInputRef.value.click(); } }; <!-- 上传按钮 --> <div v-if="actionLayout.includes(`upload`) && fileSources.length < props.maxCount" class="upload-button-container" title="点击上传文件" @click="triggerFileSelect"> <!-- 上传图标 --> <!-- <el-icon> <Plus /></el-icon> --> <!-- 上传按钮(包含上传图标) --> <el-button type="primary" :icon="Plus" circle size="small" /> <input ref="fileInputRef" type="file" multiple style="display: none" @change="handleFileSelect" /> </div>

点击一下div(class="upload-button-container"),执行两次triggerFileSelect,多次触发(事件冒泡)的应用情况:

这个问题是因为事件冒泡导致的多次触发。当你点击上传按钮时,事件触发了两次:

  1. 第一次是你实际点击div.upload-button-container时触发

  2. 第二次是因为fileInputRef.value.click()触发了 input 的 click 事件,这个事件又冒泡到了父元素

可以修改代码,在调用triggerFileSelect时传递事件对象,并在触发 input 点击前阻止事件冒泡:

vue

<script setup lang="ts"> // ... 其他代码保持不变 ... // 触发文件选择 const triggerFileSelect = (event?: Event) => { console.log("触发文件选择"); console.log("事件目标:", event?.target); console.log("当前目标:", event?.currentTarget); console.log("事件路径:", event?.composedPath()); // 阻止事件冒泡,避免多次触发 if (event) { event.stopPropagation(); } if (fileInputRef.value) { fileInputRef.value.click(); } }; // ... 其他代码保持不变 ... </script> <template> <div class="file-selector-container"> <!-- 文件列表区域 --> <div class="file-list-container"> <!-- ... 其他代码保持不变 ... --> <!-- 上传按钮 --> <div v-if="actionLayout.includes(`upload`) && fileSources.length < props.maxCount" class="upload-button-container" title="点击上传文件" @click="triggerFileSelect($event)"> <!-- 这里传递 $event --> <!-- 上传图标 --> <!-- <el-icon> <Plus /></el-icon> --> <!-- 上传按钮(包含上传图标) --> <el-button type="primary" :icon="Plus" circle size="small" /> <input ref="fileInputRef" type="file" multiple style="display: none" @change="handleFileSelect" /> </div> </div> <!-- ... 其他代码保持不变 ... --> </div> </template>

或者,更简单的解决方案是直接阻止 input 元素的点击事件冒泡:

vue

<template> <div class="file-selector-container"> <!-- 文件列表区域 --> <div class="file-list-container"> <!-- ... 其他代码保持不变 ... --> <!-- 上传按钮 --> <div v-if="actionLayout.includes(`upload`) && fileSources.length < props.maxCount" class="upload-button-container" title="点击上传文件" @click="triggerFileSelect"> <!-- 上传图标 --> <!-- <el-icon> <Plus /></el-icon> --> <!-- 上传按钮(包含上传图标) --> <el-button type="primary" :icon="Plus" circle size="small" /> <!-- 添加 @click.stop 阻止事件冒泡 --> <input ref="fileInputRef" type="file" multiple style="display: none" @change="handleFileSelect" @click.stop /> </div> </div> <!-- ... 其他代码保持不变 ... --> </div> </template>

第二种方法更简洁,直接在 input 元素上使用@click.stop阻止其点击事件冒泡到父元素,这样就不会触发两次了。

选择其中一种方法即可解决问题。推荐第二种方法,因为它更简洁且语义更清晰。


修改后的代码:

// 触发文件选择 const triggerFileSelect = (event?: Event) => { console.log("触发文件选择"); console.log("事件目标:", event?.target); console.log("当前目标:", event?.currentTarget); console.log("事件路径:", event?.composedPath()); if (fileInputRef.value) { fileInputRef.value.click(); } }; <!-- 上传按钮 --> <div v-if="actionLayout.includes(`upload`) && fileSources.length < props.maxCount" class="upload-button-container" title="点击上传文件" @click="triggerFileSelect"> <!-- 上传图标 --> <!-- <el-icon> <Plus /></el-icon> --> <!-- 上传按钮(包含上传图标) --> <el-button type="primary" :icon="Plus" circle size="small" /> <!-- 使用 @click.stop 阻止事件冒泡,从而解决点击div(class="upload-button-container"),执行两次triggerFileSelect --> <input ref="fileInputRef" type="file" multiple style="display: none" @change="handleFileSelect" @click.stop /> </div>

应用效果:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/6 7:10:00

提升Vue开发效率:Vetur完整指南

以下是对您提供的博文《提升Vue开发效率:Vetur完整技术分析指南》的 深度润色与重构版本 。本次优化严格遵循您的全部要求: ✅ 彻底去除AI痕迹,语言自然、专业、有“人味”——像一位在一线带团队写Vue、调过无数Vetur坑的资深前端工程师在分享; ✅ 打破模板化结构(无…

作者头像 李华
网站建设 2026/3/5 10:59:51

HG-ha/MTools部署进阶:自定义CUDA版本适配指南

HG-ha/MTools部署进阶&#xff1a;自定义CUDA版本适配指南 1. 开箱即用&#xff1a;为什么MTools值得你第一时间尝试 HG-ha/MTools 不是又一个功能堆砌的“大杂烩”工具&#xff0c;而是一款真正从用户工作流出发设计的现代化桌面集成环境。它把日常高频使用的图像处理、音视…

作者头像 李华
网站建设 2026/2/28 15:56:51

大文件处理新范式:File Splitter高效解决方案

大文件处理新范式&#xff1a;File Splitter高效解决方案 【免费下载链接】FileSplitter 项目地址: https://gitcode.com/gh_mirrors/fi/FileSplitter 在数据爆炸的时代&#xff0c;大文件处理已成为开发者、运维人员和数据分析师的日常挑战。无论是动辄几十GB的数据库…

作者头像 李华
网站建设 2026/3/6 18:40:54

零门槛掌握RFSoC开发:7天实战攻略

零门槛掌握RFSoC开发&#xff1a;7天实战攻略 【免费下载链接】RFSoC-Book Companion Jupyter Notebooks for the RFSoC-Book. 项目地址: https://gitcode.com/gh_mirrors/rf/RFSoC-Book RFSoC-Book是基于PYNQ和RFSoC平台的开源项目&#xff0c;通过Jupyter Notebook教程…

作者头像 李华
网站建设 2026/3/6 15:56:16

Clawdbot整合Qwen3-32B惊艳效果:多语言混合输入、中英混排代码生成

Clawdbot整合Qwen3-32B惊艳效果&#xff1a;多语言混合输入、中英混排代码生成 1. 为什么这次整合让人眼前一亮 你有没有试过在同一个提示词里&#xff0c;既写中文需求说明&#xff0c;又夹杂英文技术术语&#xff0c;再贴一段Python代码片段&#xff0c;最后还要求用日文注…

作者头像 李华
网站建设 2026/3/4 11:16:54

5步搞定CLAP音频分类部署:支持MP3/WAV文件智能识别

5步搞定CLAP音频分类部署&#xff1a;支持MP3/WAV文件智能识别 你是否遇到过这样的场景&#xff1a;手头有一堆现场采集的环境音、宠物叫声、工业设备异响&#xff0c;却要靠人工逐条听辨归类&#xff1f;或者想快速验证一段录音里是否包含特定声音事件&#xff0c;但又不想从…

作者头像 李华