vue3 + elementplus + koa2 + formData实现文件上传
大概思路
1、前端:使用formData(不会的话可以百度使用方式),将上传的文件和要传送到后台的其他数据一起放入formdata,请求后台接口的时候,参数为formdata即可 2、后台服务器:接收前端传输过来的数据,文件和其它数据要分开接收。这里涉及两个操作:①将文件写入文件夹②更新数据库
1、前端页面
<el-upload class="avatar-uploader" action="https://jsonplaceholder.typicode.com/posts/" :show-file-list="false" list-type="picture-card" :on-success="handleAvatarSuccess" :before-upload="beforeAvatarUpload" > <!--上传图片之后图片预览--> <img v-if="imageUrl" :src="imageUrl" class="avatar" /> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload>
//新增用户上传头像成功 const handleAvatarSuccess = (res, file) => { console.log(file) imageUrl.value = URL.createObjectURL(file.raw); files.value = file.raw; // console.log(imageUrl.value,"新增上传的头像",file.raw,"文件") };
//新增用户获取用户头像和用户信息 const getImg = (val) => { let formData = new FormData(); if(files.value){ formData.append("file", files.value);//获取文件信息 // console.log("上传文件了",files.value); } if(val == 0){ formData.append("userInfo", JSON.stringify(state.form));//把新增的用户信息装进去一并传到后台,对象要序列化,不然后台很可能取不到值 }else{ formData.append("userInfo", JSON.stringify(state2.form2)); } // console.log("表单的值",state2.form2); return formData; } //点击新增请求接口 const getForm = () => { const formData = getImg(0); state.dialogFormVisible = false; request.request({ url:/api/user/addUser, method:post, data:formData, //这一句一定不能掉,要不然后台无法解析 headers:{Content-Type:multipart/form-data} }).then(res => { //处理结果 }else{ })
2、Koa2后台服务器接口
(1)准备工作(app.js当中)
const koaBody = require(koa-body); //解析上传文件的插件 //处理静态资源文件 // const views = require("koa-views"); const serve = require("koa-static"); // npm install --save koa-static const mount = require("koa-mount"); //npm install koa-mount //koa-mount帮助文档链接:
app.use(koaBody({ multipart: true, formidable: { maxFileSize: 2000 * 1024 * 1024 // 设置上传文件大小最大限制,默认2M } }))
//不将根暴露出去,暴露upload文件 app.use(mount(/upload,serve(path.join( __dirname,./upload))));
2、接口
const fs = require(fs); //管理员新增用户 router.post(/addUser,async(ctx) => { let file = ctx.request.files.file; let addUserInfo = JSON.parse(ctx.request.body.userInfo); //查询用户是否存在 const project = await userModel.findOne({ where: { username:addUserInfo.username, password: addUserInfo.password } }); if(project===null){ if(file != null){ // 创建可读流 const reader = fs.createReadStream(file.path); const fileResource = process.cwd()+/upload + `/${file.name}`; // 创建可写流 const upStream = fs.createWriteStream(fileResource); // 可读流通过管道写入可写流 reader.pipe(upStream); } const newUser = await userModel.create({ headPic:file.name,//数据库只存图片的名字 username: addUserInfo.username, password: addUserInfo.password, role: addUserInfo.role, status: addUserInfo.status, }); if(newUser){ ctx.body=formatResponse("200",newUser,"success"); }else{ ctx.body=formatResponse("500",{msg:"新增失败!"},"fail"); } }else{ ctx.body=formatResponse("500",{msg:"该用户已存在!"},"fail"); } });
最后,在上传多个文件可能会出现的问题
上传多个文件,可以用遍历的方式,一个一个加进去 this.files.forEach(item => { formData.append("file", item); });