vue点击上传图片并实现图片预览功能,并实现多张图片放到一个数组中进行后端请求(使用原生input)

一、将 File 对象转成 BASE64 字符串 (FileReader)

<template><div><!-- 用来显示封面的图片 --><!-- <img src="@/assets/images/cover.jpg" alt="" class="cover-img" ref="imgRef" /> --><img :src="previewImg" alt="" class="cover-img" ref="imgRef" /><br /><!-- 文件选择框,默认被隐藏 --><input @change="coverImgChangeHandler" type="file"  accept="image/*" ref="iptFileRef" hidden/><!-- 选择封面的按钮 --><button type="text" @click="choosecoverImgHandler">+ 选择封面</button></div>
</template><script>
// ◆导入默认图片, webpack 就会进行打包
import coverImg from '@/assets/images/cover.jpg'
export default {data () {return {// ◆把默认图片赋值给封面图片显示previewImg: coverImg}},methods: {// ◆点击选择封面,触发图片选择框的点击事件choosecoverImgHandler () {this.$refs.iptFileRef.click()},// ◆图片选择框的 change 事件触发coverImgChangeHandler (e) {console.log(e.target.files)// 1.获取用户选择的文件对象const files = e.target.files// 2.判断用户是否选择了文件对象if (files.length === 0) {// 2.1用户没有选择图片(使用默认图片)// 法1// this.$refs.imgRef.src = coverImg// 法2this.previewImg = coverImg} else {// 2.2用户选择了图片(使用选择的图片)// ◆将 File 对象 转成 BASE64 字符串 // 1.创建 FileReader 对象const fr = new FileReader()// 2.调用 readAsDataURL 函数,读取文件内容fr.readAsDataURL(files[0])// 3.监听 fr 的 onload 事件fr.onload = (e) => {// 通过 e.target.result 获取到读取的结果,值是 BASE64 格式的字符串// 法1// this.$refs.imgRef.src = e.target.result// 法2this.previewImg = e.target.result}}}}
}
</script><style lang="less" scoped>
// 设置图片封面的宽高
.cover-img {width: 400px;height: 280px;object-fit: cover;
}
</style>

二、将 File 对象转成 url

<template><div><!-- 用来显示封面的图片 --><img :src="previewImg" alt="" class="cover-img" ref="imgRef" /><br /><!-- 文件选择框,默认被隐藏 --><input @change="coverImgChangeHandler" type="file"  accept="image/*" ref="iptFileRef" hidden/><!-- 选择封面的按钮 --><button type="text" @click="choosecoverImgHandler">+ 选择封面</button></div>
</template><script>
// ◆导入默认图片, webpack 就会进行打包
import coverImg from '@/assets/images/cover.jpg'
export default {data () {return {// ◆把默认图片赋值给封面图片显示previewImg: coverImg}},methods: {// ◆点击选择封面,触发图片选择框的点击事件choosecoverImgHandler () {this.$refs.iptFileRef.click()},// ◆图片选择框的 change 事件触发coverImgChangeHandler (e) {console.log(e.target.files)// 1.获取用户选择的文件对象const files = e.target.files// 2.判断用户是否选择了文件对象if (files.length === 0) {// 2.1用户没有选择图片(使用默认图片)this.previewImg = coverImg} else {// 2.2用户选择了图片(使用选择的图片)// 将 File 对象转成 urlthis.previewImg = URL.createObjectURL(files[0])}}}
}
</script><style lang="less" scoped>
// 设置图片封面的宽高
.cover-img {width: 400px;height: 280px;object-fit: cover;
}
</style>

三、总结与思考

总结

  • 设置默认图片:将图片作为模块导入,定义变量接收,赋值给图片的 src
    • 其他方法:使用自定义指令设置默认图片、在模板中使用 v-if
  • 点击上传图片按钮,触发图片输入框的 click 事件
    • 隐藏图片输入框:hiddendisplay:none
  • 绑定图片输入框 的 change 事件,获取文件对象 e.target.files
  • 判断 e.target.fileslength
    • 长度为0:用户取消选择图片,传给后台的数据就是 null,把默认图片赋值给当前预览区
    • 长度为1:用户确认选择图片,把 e.target.files[0]传给后台
  • 用户选择了图片之后,预览图片的方法:
    • 将获取的文件对象转成 BASE64 字符串:小图片
    • 将获取的文件对象转成 url:大图片

思考

为什么当用户选择了图片之后,我们不把 e.target.files[0] 直接赋值给预览图片的 srcpreviewImg,而传给后台就可以?

首先src 只支持 urlBASE64 字符串,而当后台需要的数据类型是 Blob 时,我们就可以直接把 e.target.files[0] 传给它,因为 File 就是 Blob 的子类,关系就像 ArrayObject 的关系一样。

进阶

一般进行身份认证时会上传身份证正反面,如果这时后端要求将两张身份证图片放到一个数组中进行请求应该如何做到呢?

首先,我们已经通过输入框 的 change 事件,获取到了文件对象 e.target.files e.target.files[0]为单个文件,将拿到的单个文件push到新的数组中,以下代码为vue3语法实现

//显示图片(图片预览方法)
export const readUrl=(file,preImg)=>{const fr = new FileReader()fr.readAsDataURL(file)fr.onload = (e) => {preImg.value = e.target.result//preImg为预览图片的数据}
}
//此为input框的change事件,以此拿到单个文件
const coverImgChangeHandler= (e)=> {form.value.authFiles.push(e.target.files[0])readUrl(e.target.files[0],previewImg)
}
//提交认证按钮
const submitForm =async (formEl: FormInstance | undefined) => {if (!formEl) returnawait formEl.validate((valid, fields) => {if (valid) {let formData = new FormData();//此处为重点!!记得遍历后再append,直接append报错form.value.authFiles.forEach((file) =>{formData.append('authFiles',file)})// console.log(formData)axios.post('url',formData).then((res) => {console.log(res)}).catch(err => {// console.log(err);})} else {// console.log('提交失败', fields)}})}

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

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

相关文章

html基础(2)(链接、图像、表格、列表、id、块)

1、链接 <a href"https://www.example.com" target"_blank" title"Example Link">Click here</a> 在上示例中&#xff0c;定义了一个链接&#xff0c;在网页中显示为Click here&#xff0c;鼠标悬停指示为Example Link&#xff0c…

Java(多线程)

一、基本概念 进程&#xff1a;一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元&#xff0c;在传统的操作系统中&#xff0c;进程既是基本的分配单元&#xff0c;也是基本的执行单元。线程&#xff1a;操作系统中能够进行运算的最…

java Web课程管理系统用eclipse定制开发mysql数据库BS模式java编程jdbc

一、源码特点 JSP 课程管理系统是一套完善的web设计系统&#xff0c;对理解JSP java 编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,eclipse开发&#xff0c;数据库为Mysql5.0&#xff0c;使用ja…

贪心算法|406.根据身高重建队列

力扣题目链接 class Solution { public:static bool cmp(const vector<int>& a, const vector<int>& b) {if (a[0] b[0]) return a[1] < b[1];return a[0] > b[0];}vector<vector<int>> reconstructQueue(vector<vector<int>…

骑砍2霸主MOD开发(2)-基础开发环境搭建

一.骑砍2霸主程序架构 二.骑砍2霸主C#接口层代码查看 1.C#反编译工具dnspy下载: 2.骑砍2霸主游戏引擎接口查看: 例如IMBAgent interface接口: #调用TaleWorlds.Native.dll中的函数 [EngineMethod("get_movement_flags", false)] uint GetMovementFlags(UIntPtr agen…

Visual Studio Code SSH 连接远程服务器

Visual Studio Code通过 SSH 连接远程服务器并实现免密登录&#xff0c;你可以按照以下步骤进行操作&#xff1a; 1. **安装插件**&#xff1a;首先&#xff0c;在 VS Code 中安装 "Remote - SSH" 插件。打开 VS Code&#xff0c;点击左侧的扩展图标&#xff0c;搜索…

微服务学习3

目录 1.微服务保护 1.1.服务保护方案 1.1.1.请求限流 1.1.2.线程隔离 1.1.3.服务熔断 1.2.Sentinel 1.2.1.微服务整合 1.2.2.请求限流 1.3.线程隔离 1.3.1.OpenFeign整合Sentinel 1.3.2.配置线程隔离 1.4.服务熔断 1.4.1.编写降级逻辑 1.4.2服务熔断 2.分布式事…

mp4转flv怎么转?电脑怎么把视频转成flv?

MP4&#xff08;MPEG-4 Part 14&#xff09;是一种多媒体容器格式&#xff0c;广泛用于包含视频、音频、字幕等多种数据流。MP4因其高度灵活性、压缩效率和兼容性成为视频领域的主流格式&#xff0c;支持范围涵盖从在线视频到移动设备的各类应用场景。 FLV文件格式的多个优点 …

scFed:联邦学习用于scRNA-seq分类

scRNA-seq的出现彻底改变了我们对生物组织中细胞异质性和复杂性的理解。然而&#xff0c;大型&#xff0c;稀疏的scRNA-seq数据集的隐私法规对细胞分类提出了挑战。联邦学习提供了一种解决方案&#xff0c;允许高效和私有的数据使用。scFed是一个统一的联邦学习框架&#xff0c…

Spring Validation解决后端表单校验

NotNull&#xff1a;从前台传递过来的参数不能为null,如果为空&#xff0c;会在控制台日志中把message打印出来 Range&#xff1a;范围&#xff0c;最大多少&#xff0c;最小多少 Patten&#xff0c;标注的字段值必须符合定义的正则表达式&#xff08;按照业务规则&#xff0…

Android OOM问题定位、内存优化

一、常用工具&#xff1a; 1、LeakCanary val refWatcher: RefWatcher? TestApp.getRefWatcher(activity) refWatcher?.watch(activity);//检测是否有泄露&#xff0c;即触发GC回收&#xff0c;看activity是否被回收&#xff0c;没有被回收就是泄露了。 二、常见的几种内…

TCP 重传、滑动窗口、流量控制、拥塞控制(计算机网络)

重传机制 TCP 针对数据包丢失的情况&#xff0c;会用重传机制解决。 接下来说说常见的重传机制&#xff1a; 超时重传快速重传SACKD-SACK 超时重传 重传机制的其中一个方式&#xff0c;就是在发送数据时&#xff0c;设定一个定时器&#xff0c;当超过指定的时间后&#xff0c…

实验2 路由器基本配置

实验2 路由器基本配置 一、 原理描述二、 实验目的三、 实验内容四、 实验步骤1.建立实验拓扑2.基础配置3.配置路由器接口IP地址4.查看路由器配置信息5.连通性测试6.使用抓包工具 一、 原理描述 华为设备支持多种配置方式&#xff0c;操作人员要熟悉使用命令行的方式进行设备管…

SecureCRT通过私钥连接跳板机,再连接到目标服务器(图文教程)

文章目录 1. 配置第一个session&#xff08;跳板机&#xff09;2. 设置本地端口3. 设置全局firewall4. 配置第二个session&#xff08;目标服务器&#xff09; 服务器那边给了一个私钥&#xff0c;现在需要通过私钥连接跳板机&#xff0c;再连接到目标服务器上 &#x1f349; …

算法打卡day40|动态规划篇08| Leetcode 139.单词拆分|多重背包理论|背包问题总结篇

目录 算法题 Leetcode 139.单词拆分 个人思路 解法 动态规划 回溯法 多重背包理论基础 背包问题总结篇 解题思路 背包递推公式 遍历顺序 01背包 完全背包 算法题 Leetcode 139.单词拆分 题目链接:139.单词拆分 大佬视频讲解&#xff1a;单词拆分视频讲解 个人思…

Redis系列之基于Linux单机安装

Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库&#xff0c;并提供多种语言的 API。最近学习需要用到Redis&#xff0c;所以就去Linux服务器上部署一个&#xff0c;做下记录&#xff0c;方便…

【架构师】-- 浅淡架构的分类

什么是架构&#xff1f; 说到架构&#xff0c;这个概念没有很清晰的范围划分&#xff0c;也没有一个标准的定义&#xff0c;每个人的理解可能都不一样。 架构在百度百科中是这样定义的&#xff1a;架构&#xff0c;又名软件架构&#xff0c;是有关软件整体结构与组件的抽象描…

llama2.c与chinese-baby-llama2语言模型本地部署推理

文章目录 简介Github文档克隆源码英文模型编译运行中文模型&#xff08;280M&#xff09;main函数 简介 llama2.c是一个极简的Llama 2 LLM全栈工具&#xff0c;使用一个简单的 700 行 C 文件 ( run.c ) 对其进行推理。llama2.c涉及LLM微调、模型构建、推理端末部署&#xff08…

[计算机效率] 鼠标手势工具:WGestures(解放键盘的超级效率工具)

3.22 鼠标手势工具&#xff1a;WGestures 通过设置各种鼠标手势和操作进行绑定。当用户通过鼠标绘制出特定的鼠标手势后就会触发已经设置好的操作。有点像浏览器中的鼠标手势&#xff0c;通过鼠标手势操纵浏览器做一些特定的动作。这是一款强大的鼠标手势工具&#xff0c;可以…

机器学习(理论第一课)

一、理解人工智能、机器学习、深度学习、强化学习&#xff1f; 人工智能、机器学习和深度学习之间存在递进关系&#xff0c;它们的覆盖范围逐层递减。 **人工智能&#xff08;Artificial Intelligence&#xff0c;AI&#xff09;**是最宽泛的概念&#xff0c;旨在研究、开发用于…