当前位置: 首页 > news >正文

Vue3+Koa2实现图片上传(不再畏惧)

大家好,我是勇宝,一个热爱前端的小学生,年关将至,提前祝大家新年快乐。今天呢,我们就来好好的啃一啃图片上传,从一个前端开发者的角度来探讨一下图片上传前后端到底都做了哪些事情。

文章目录

    • 一、技术摘要
    • 二、图片上传流程概述
      • 1. 前端
      • 2. 后端
    • 三、项目搭建
      • 前端
        • 1. 初始化Vue
      • 后端(koa2)
        • 1. 全局安装脚手架
        • 2. 初始化项目
        • 3. 运行
    • 四、开始撸代码
      • 1. 编写html骨架
      • 2. 定义回显元素
      • 3. 编写选择按钮逻辑
      • 4. 回显选择的图片
      • 5. 编写上传图片按钮
      • 6. 编写后端代码
      • 小结
    • 五、总结

一、技术摘要

本次实现的Demo使用到的技术主要有如下:

  • Vue3: 是一款用于构建用户界面的 JavaScript 框架。
  • koa: 基于 Node.js 平台的下一代 web 开发框架。

以上就是我们本次要用到的一些技术栈,我把官方也给大家贴心的贴出来了,方便大家学习,任何技术都离不开原生,大家多多举一反三。

二、图片上传流程概述

从概念的角度给大家伙梳理一下图片上传要做哪些事情。

1. 前端

首先我们要知道图片上传的一个大概的流程是什么,前端做点啥?后端做点啥?

我用最原生的方式给大家唠一唠,首先呢这个前端有一个<input id="file_upload" type="file" accept="image/*" />标签,这个大家应该没忘记吧。

一般我们是把这个input隐藏,自己写那么几个小按钮,通过点击按钮触发input点击事件(click)来选择要上传的图片对吧。

然后就是回显的方式,一般有两种:

  • 一种是等待后端处理好之后,response返回给我们前端然后去挂载。
  • 还有一种就是我们前端解析好之后去显示,这种比较好,不浪费服务器资源,哈哈哈。

最后的最后就是我们的请求头要改为multipart/form-data

2. 后端

首先是编写我们图片上传的接口uploads。因为这里我演示的是koa这个框架,所有后端我们使用到@koa/multur这个插件。

设置我们图片存放的路径(文件夹),当我们存储成功之后,再把图片信息存入我们的数据库(这一步就不给大家演示了,况且我也就会个MongoDB,就不献丑了),最后返回给前端成功的状态码

三、项目搭建

这一块没有什么难度,我们简单带过。

前端

1. 初始化Vue
// 初始化模版
npm init vue@latest
// 安装依赖
npm install
// 需要用到 axios HTTP请求
npm install axios --save

后端(koa2)

我千辛万苦找了一个生成koa的脚手架,还不错。

1. 全局安装脚手架
npm install koa-generator -g
2. 初始化项目
// serve是项目名称,可以自定义
koa2 serve
// 安装项目依赖
npm install
3. 运行
npm run dev

四、开始撸代码

前期工作准备好之后,开始进入我们的正题

1. 编写html骨架

我们就写两个按钮,一个用来选择图片,一个用来上传到后端

<template><div class="upload"><input type="file" accept="image/*" class="upload-file" ref="selectFileRef" /><div class="upload-btns"><button class="upload-select">选择图片</button><button class="upload-current">上传图片</button></div><!-- 用来回显我们的图片 --><div class="upload-preview"><img src="" alt="图片" /></div></div>
</template>
<script setup>
</script>
<style lang="scss" scoped>
.upload-file {
display: none;
}
</style>

2. 定义回显元素

如果我们的回显src是空的话,我们就让它隐藏。

<div class="upload-preview" v-show="previewUrl"><img src="" alt="图片" />
</div><script>
import { ref } from 'vue'
const previewUrl = ref('')
</script>

3. 编写选择按钮逻辑

使用ref获取inputDOM元素,通过点击选择图片按钮,触发input点击事件。

<button class="upload-select" @click="selectFileRef.click">选择图片</button>
......
......
// 获取input元素
const selectFileRef = ref(null)

此时我们点击选择图片,浏览器就会弹框,就可以选择我们要上传的图片啦!

4. 回显选择的图片

我们使用上边提到的第一种回显的方式,这样会减少http请求次数,减小服务器端压力。这里我们要监听input元素的change事件,当我们确定选择好图片之后会触发这个事件。具体如下:

<input type="file" accept="image/*" class="upload-file" ref="selectFileRef" @change="showImg" />
......
......const showImg = () => {// 获取我们上传的元素const file = selectFileRef.value.files[0]// 把图片转成base64const reader = new FileReader()reader.readAsDataURL(file)reader.onload = () => {// 给我们的回显元素赋值previewUrl.value = reader.result}}

5. 编写上传图片按钮

这是前端的最后一小步啦,这里我们主要注意请求header设置,还有数据类型{"Content-Type": "multipart/form-data"},并且这里我们使用到了axios

这里我就把axios直接拿过来用一下啦,以后有时间,我单独好好的和小伙伴们唠一唠怎么好好的对axios进行二次封装。

<button class="upload-current" @click="upload">上传图片</button>
......
......
// 编写上传文件的处理逻辑方法
const upload = () => {const file = selectFileRef.value.files[0]const formData = new FormData()formData.append('files', file)reader.onload = () => {previewUrl.value = reader.result}// 使用axios发起http请求axios({method: 'post',url: 'http://localhost:3000/uploads',headers: {'Content-Type': 'multipart/form-data'},data: formData}).then(res => {//这里是后端返回给我们的结果})
}

6. 编写后端代码

后端不作为我们的重点,大概给大家撸一下代码,主要是编写我们的app.js文件。还需要安装一下@koa/multer模块。

npm install @koa/multer

编写app.js

const Koa = require("koa");
const Router = require("koa-router");
const multer = require("@koa/multer");const app = new Koa();
const router = new Router();// 配置multer中间件
const upload = multer({storage: multer.diskStorage({//文件上传保存的路径destination: function (req, file, cb) {let dir = "./public/images"// 查看是否存在,不存在就创建if (!fs.existsSync(dir)) {fs.mkdirSync(dir, {recursive: true})}// 这里的路径必须要存在cb(null, dir)},//修改文件名称filename: function (req, file, cb) {const fileName = file.fieldname + "-" + Date.now() + path.extname(file.originalname)cb(null, fileName)}})
})// 编写图片上传的接口
router.post('/uploads', upload.single('files'), async ctx => {const filename = ctx.request.file.filenamepath = ctx.request.origin + '/images/' + filename// 这里可以去操作数据库把我们的url存入数据库中方便使用。ctx.body = {code: 200,message: '图片上传成功',url: path}
})
......
......
app.use(router.routes(), router.allowedMethods())app.listen(3000, () => {console.log('This is port 3000...')
})

小结

到此图片上传功能完成,大家可以愉快的玩耍啦。其实大家只要把该注意的点都写到基本就问题不大了。

五、总结

图片上传可以说是一个老生常谈的问题了,对于小白来说的我,每次看到就头大,但是这是不对的,我们应该有着一颗敢于探索敢于学习的精神,于是就决心狠狠的给它啃下。当你学会一项技能的时候就会发现,原来是如此简单(这是我作为小白的客观评价,大佬勿喷,哈哈哈)。遇到困难分两种:一种是知难而退、一种是迎难而上,这也是人和人之间有差距的根本原因

好了,今天就说道这把,大家共勉。

相关文章:

Vue3+Koa2实现图片上传(不再畏惧)

大家好&#xff0c;我是勇宝&#xff0c;一个热爱前端的小学生&#xff0c;年关将至&#xff0c;提前祝大家新年快乐。今天呢&#xff0c;我们就来好好的啃一啃图片上传&#xff0c;从一个前端开发者的角度来探讨一下图片上传前后端到底都做了哪些事情。 文章目录 一、技术摘要…...

wsl-ubuntu 安装 nginx

wsl-ubuntu 安装 nginx 1. 安装 nginx2. 确认 nginx 启动状态3. 重启 nginx4. 停止 nginx 1. 安装 nginx sudo apt install nginx2. 确认 nginx 启动状态 systemctl status nginx3. 重启 nginx systemctl restart nginx4. 停止 nginx systemctl stop nginx完成&#xff01;…...

重学Ajax

摘要&#xff1a;AJAX是一个在前端的应用非常广泛技术&#xff0c;为什么还要谈它呢&#xff1f;么得办法之前学的不全面&#xff0c;再收拾收拾。水平有限&#xff0c;欢迎指正&#xff01; AJAX&#xff08;全称&#xff1a;Asynchronous JavaScript and XML&#xff09;是一…...

springboot3+vue3支付宝交易案例-结算支付

springboot3vue3支付宝交易案例-结算支付&#xff01;今天下午整理了一下结算的内容。遇到了很多问题。汇总分享给大家。 第一个问题&#xff1a;支付宝结算后&#xff0c;返回的交易编码&#xff0c;和交易时间&#xff0c;交易状态&#xff0c;都应该使用varchar来存。 第二…...

c语言 ceil() 函数

ceil()是C语言中的一个数学函数&#xff0c;用于向上取整。它的函数原型定义在math.h头文件中。 ceil()函数的作用是返回一个大于或等于给定参数的最小整数值&#xff0c;即将参数向上取整到最接近的整数。返回值的数据类型为double。 以下是ceil()函数的函数原型&#xff1a…...

virtualBox虚拟机安装ubuntu后的必要配置

1. 使能双向copy 粘贴功能。在device menu的 shared clipboard项, 选bidirectional. 2.启用共享文件夹。 在device 菜单的 shared folder 项配置&#xff0c; (对于日期乱码问题和命令行打不开的问题请见ubuntu18.04安装后时间日期乱码及terminal打不开解决方法_电脑日期变成…...

《Pandas 简易速速上手小册》第6章:Pandas 时间序列分析(2024 最新版)

文章目录 6.1 时间序列数据基础6.1.1 基础知识6.1.2 重点案例&#xff1a;股票市场分析6.1.3 拓展案例一&#xff1a;温度变化分析6.1.4 拓展案例二&#xff1a;电商平台日销售额分析 6.2 日期与时间功能6.2.1 基础知识6.2.2 重点案例&#xff1a;活动日志分析6.2.3 拓展案例一…...

滇西科技师范学院食堂大宗物资采购项目(冰冻制品类)招标公告

滇西科技师范学院食堂大宗物资采购项目(冰冻制品类)招标公告 (招标编号&#xff1a;YDZOH20240158) 项目所在地区&#xff1a;云南省,临沧市,市辖区 一、招标条件 本滇西科技师范学院食堂大宗物资采购项目(冰冻制品类)已由项目审批/核准/备案机关批准&#xff0c;项目资金来源为…...

(2024,SaFaRI,双三上采样和 DFT,空间特征和频率特征)基于扩散模型的图像空间和频率感知恢复方法

Spatial-and-Frequency-aware Restoration method for Images based on Diffusion Models 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 3. 方法 3.1 修改数据保真度 3.2 …...

【Linux】环境基础开发工具的使用之gcc详解(二)

前言&#xff1a;上一篇文章中我们讲解了Linux下的vim和yum的工具的使用&#xff0c;今天我们将在上一次的基础上进一步的讲解开放工具的时候。 &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:Linux的深度刨析 &#x1f448; &#x1f4a…...

go语言-用channel控制goroutine的退出

用channel控制goroutine的退出 本文简要介绍了&#xff0c;如何用channel控制goroutine的退出的基本方法 for-range主动停止goruitine package mainimport ("fmt""sync""time" )/* Go并发编程模型&#xff1a;主动停止goroutine 方法一&#…...

强大的虚拟机Parallels Desktop 19 mac中文激活

Parallels Desktop是一款功能全面、易于使用的虚拟机软件&#xff0c;它为用户提供了在Mac电脑上同时运行多个操作系统的便利。 软件下载&#xff1a;Parallels Desktop 19 mac中文激活版下载 Parallels Desktop 19 mac具有快速启动和关闭虚拟机的能力&#xff0c;让用户能够迅…...

单元测试框架深入(一):单元测试框架深入

一、一个简单的例子 1、引入Maven依赖&#xff1a;JUnit框架和Surefire插件 2.在src/test/java目录下新建名字以“Test”结尾的测试类&#xff0c;并用Test注释测试方法 3.运行单元测试用例 或用mvn命令运行单元测试&#xff1a; 二、单元测试基础之单元测试框架&#xff1a;J…...

苏门X学士常识学习

前言 苏轼&#xff08;1037年—1101年&#xff09;是北宋的文坛领袖&#xff0c;很喜欢奖掖后进。其门下最有名的是“苏门四学士”&#xff0c;另外还有“苏门六学士”和“苏门后四学士”之说。 一、苏门四学士 苏轼在《与李昭玘书》中说&#xff1a; 轼蒙庇粗遣&#xff0…...

MD5算法:高效安全的数据完整性保障

摘要&#xff1a;在数字世界中&#xff0c;确保数据完整性和安全性至关重要。消息摘要算法就是一种用于实现这一目标的常用技术。其中&#xff0c;Message Digest Algorithm 5&#xff08;MD5&#xff09;算法因其高效性和安全性而受到广泛关注。本文将详细介绍MD5算法的优缺点…...

JavaScript基础五对象 内置对象 Math.random()

内置对象-生成任意范围随机数 Math.random() 随机数函数&#xff0c; 返回一个0 - 1之间&#xff0c;并且包括0不包括1的随机小数 [0, 1&#xff09; 如何生成0-10的随机数呢&#xff1f; Math.floor(Math.random() * (10 1)) 放大11倍再向下取整 如何生成5-10的随机数&…...

curl之网络接口

Curl_cftype 连接接口定义 struct Curl_cftype {const char *name; /* name of the filter type */int flags; /* flags of filter type */int log_level; /* log level for such filters */Cu…...

Pytest中doctests的测试方法应用

在 Python 的测试生态中,Pytest 提供了多种灵活且强大的测试工具。其中,doctests 是一种独特而直观的测试方法,通过直接从文档注释中提取和执行测试用例,确保代码示例的正确性。本文将深入介绍 Pytest 中 doctests 的测试方法,包括基本用法和实际案例,以帮助你更好地利用…...

Android 8.1 铃声音量通话音量同步调节

Android 8.1 铃声音量通话音量同步调节 最近收到客户反馈&#xff0c;想要实现铃声音量通话音量同步调节&#xff0c;具体修改参照如下&#xff1a; /frameworks/base/core/java/android/preference/SeekBarVolumizer.java if (defaultUri null) {if (mStreamType AudioMan…...

C++——字符串string

C——字符串string C语言中对字符串的表示通常用指针&#xff0c;新手会面临内存泄漏或者段错误等众多问题。 在 C 中&#xff0c; string 类是标准库的一部分&#xff0c;用于表示和操作字符串。它是对传统的 C 风格字符串&#xff08;以空 字符 ‘\0’ 结尾的字符数组&…...

大数据零基础学习day1之环境准备和大数据初步理解

学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 &#xff08;1&#xff09;设置网关 打开VMware虚拟机&#xff0c;点击编辑…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:

根据万维钢精英日课6的内容&#xff0c;使用AI&#xff08;2025&#xff09;可以参考以下方法&#xff1a; 四个洞见 模型已经比人聪明&#xff1a;以ChatGPT o3为代表的AI非常强大&#xff0c;能运用高级理论解释道理、引用最新学术论文&#xff0c;生成对顶尖科学家都有用的…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案

在大数据时代&#xff0c;海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构&#xff0c;在处理大规模数据抓取任务时展现出强大的能力。然而&#xff0c;随着业务规模的不断扩大和数据抓取需求的日益复杂&#xff0c;传统…...

《Docker》架构

文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器&#xff0c;docker&#xff0c;镜像&#xff0c;k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...

背包问题双雄:01 背包与完全背包详解(Java 实现)

一、背包问题概述 背包问题是动态规划领域的经典问题&#xff0c;其核心在于如何在有限容量的背包中选择物品&#xff0c;使得总价值最大化。根据物品选择规则的不同&#xff0c;主要分为两类&#xff1a; 01 背包&#xff1a;每件物品最多选 1 次&#xff08;选或不选&#…...