一、初始化后台项目
这里通过手动创建项目,你也可以通过脚手架创建。
创建一个文件夹font-server,执行以下初始化命令
npm init -y
npm install expres body-parser //安装express和body-parser
npm install multer --save //Multer 是一个node.js中间件,主要用于上传文件。
在font-server目录下新建文件app.js,新建文件夹upload、api。在api文件夹下新建文件upLoadImg.js。
app.js中写入代码:
// 引入express
const express = require("express")
// 创建express 实例对象
const app = express()
// 引入路由文件(即upLoadImg.js)
const router = require("./api/upLoadImg")
// 部署静态资源, 部署之后即可通过域名访问文件
app.use(express.static("upload"))
// 挂载路由
app.use("/api/upload",router)
// 监听端口
app.listen(3000,() => {
console.log("server is running...")
})
在api文件夹下的upLoadImg.js中下入代码:
// 引入express路由
const express = require("express")
const router = express.Router()
const multer = require("multer")
/*
multer是node的中间件, 处理表单数据 主要用于上传文件 multipart/form-data
*/
// 指定存储位置
const storage = multer.diskStorage({
// 存储位置
destination(req, file, callback) {
// 参数一 错误信息 参数二 上传路径(此处指定upload文件夹)
callback(null, "upload")
},
// 确定文件名
filename(req, file, cb) {
cb(null, Date.now() + file.originalname)
}
})
// 得到multer对象 传入storage对象
const upload = multer({ storage })
// 挂载中间件
router.post("/upImg", upload.single("file"), (req,res) => {
// 需要返回图片的访问地址 域名+文件名
const url = "http://localhost:3000/" + req.file.filename
res.json({url})
})
module.exports = router
二、前台调用接口实现图片上传
首先项目需要安装element-ui、axios并引用
安装:
npm i element-ui -S
npm install axios --save
npm install vue-axios --save
在main.js中引入
// 引进element-ui并挂载
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css'; //样式文件单独引入
Vue.use(ElementUI); //全局注册
//引入axios并挂载
import axios from "axios"
Vue.prototype.$axios = axios
在需要上传图片的地方使用,这里新建一个vue文件进行演示:
<template>
<div id="upload">
<!--
action 请求的路径
show-file-list 是否显示文件列表
on-success 成功之后的回调
before-upload 上传前操作
http-request 覆盖默认的上传行为,可以自定义上传的实现
更多钩子函数可查看你elementUI文档:https://element.eleme.cn/#/zh-CN/component/installation
-->
<el-upload
class="avatar-uploader"
action="/api/upload/upImg"
:show-file-list="false"
:http-request="upload"
:before-upload='ImgBeforeAvatarUpload'
>
<img v-if="imageUrl" :src="imageUrl" class="avatar" />
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
</div>
</template>
<script>
export default {
data() {
return {
imageUrl: ""
}
},
methods: {
upload(f) {
// console.log(f)
// 1. 获取表单数据 fromData 表单数据
let fromData = new FormData()
fromData.append("file", f.file)
// 2. 发起请求
this.$axios({
method: 'post',
url: f.action,
data: fromData
}).then(res => {
// 3. 请求成功之后 图片回显
console.log(res)
this.imageUrl = res.data.url
})
},
//上传前校验图片规则
ImgBeforeAvatarUpload(file) {
console.log(file)
const isJPG = file.type === "image/jpeg" || file.type === "image/png";
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG) {
this.$message.error("上传图片只能是 JPG 和 Png 格式!");
return false;
}
if (!isLt2M) {
this.$message.error("上传图片大小不能超过 2MB!");
return false;
}
},
}
};
</script>
<style>
.avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.avatar {
width: 178px;
height: 178px;
display: block;
}
</style>
最后需要解决跨域问题,vue2.X版本的在config文件夹下的index.js中,添加如下代码:
proxyTable: {
"/api/": {
target: "http://localhost:3000/api",
pathRewrite: {
"^/api/": "" // 用 "/api" 代替target中的地址 后面如果访问 http://localhost:3000/api/user/login ==> /api/user/login
}
}
},
如果有不对的地方欢迎大神们在讨论区留言交流。