前端代码:
<template> <el-row> <el-col :span="18" :offset="3"> <el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <el-form-item label="公司名称" prop="companyname"> <el-input type="text" v-model="ruleForm.companyname" autocomplete="off"></el-input> </el-form-item> <el-form-item label="认证来源" prop="source"> <el-input type="text" v-model="ruleForm.source" autocomplete="off"></el-input> </el-form-item> <el-form-item label="认证方式" prop="mode"> <el-input v-model="ruleForm.mode"></el-input> </el-form-item> <el-form-item label="姓名" prop="names"> <el-input type="text" v-model="ruleForm.names" autocomplete="off"></el-input> </el-form-item> <el-form-item label="手机号码" prop="phone"> <el-input type="text" v-model.number="ruleForm.phone" autocomplete="off"></el-input> </el-form-item> <el-form-item label="认证方式" prop="mode"> <el-radio v-model="radio" label="1">名片方式认证</el-radio> <el-radio v-model="radio" label="2">身份证+营业执照认真</el-radio> <template> <el-upload action="#" :http-request="uploadFile" :multiple="false" ref="upload" :on-success="uploadSuccess" :auto-upload="false" list-type="picture-card" :on-preview="handlePictureCardPreview" name="file" enctype="multipart/form-data" :limit="num" :on-exceed="handleExceed" accept="image/jpeg,image/gif,image/png,image/bmp"> <i class="el-icon-plus"></i> </el-upload> <el-dialog :visible.sync="dialogVisible"> <img width="100%" :src="dialogImageUrl" alt=""> </el-dialog> </template> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button> <el-button @click="resetForm('ruleForm')">重置</el-button> </el-form-item> </el-form> </el-col> </el-row> </template> <script> import { mapGetters } from 'vuex' export default { name: 'companys', computed: { ...mapGetters(['isAuth']) }, data() { return { radio: '1', ruleForm: { companyname: '', source: '', mode: '', names: '', phone: '', }, rules: { companyname: [{ required: true, message: '请输入公司名称', trigger: 'blur' }], source: [{ required: true, message: '请输入认证来源', trigger: 'blur' }], names: [{ required: true, message: '请输入认证姓名', trigger: 'blur' }], phone: [{ required: true, message: '请输入手机号码', trigger: 'blur' }], mode: [{ required: true, message: '请输输入类型', trigger: 'blur' }], }, dialogImageUrl: '', dialogVisible: false, headers: { Authorization: localStorage.getItem('Admintokens'), }, num: 1, formDate: '' } }, watch: { radio(newVal, oldVal) { this.$refs.upload.clearFiles(); this.ruleForm.fromData = []; this.num = Number(newVal) } }, methods: { //提交数据 submitForm(formName) { this.$refs[formName].validate((valid) => { if(valid) { //new 一个FormData对象 this.formDate = new FormData() this.$refs.upload.submit(); //添加额外的数据 this.formDate.append('companyname', this.ruleForm.companyname); this.formDate.append('source', this.ruleForm.source); this.formDate.append('names', this.ruleForm.names); this.formDate.append('phone', this.ruleForm.phone); this.formDate.append('mode', this.ruleForm.mode); //设置头部发送格式 let config = { headers: { 'Content-Type': 'multipart/form-data' } } this.$axios.post("/api/company/uploads", this.formDate, config).then(res => { console.log(res) }).catch(res => { console.log(res) }) } else { console.log('error submit!!'); return false; } }); }, resetForm(formName) { this.$refs[formName].resetFields(); }, //查看图片 handlePictureCardPreview(file) { this.dialogImageUrl = file.url; this.dialogVisible = true; }, //接受服务器返回的数据 uploadSuccess(response, file, fileList) { console.log(response) }, //上传失败触发 handleError(err, file, fileList) { this.$message.error('上传失败') }, //超出限制触发 handleExceed(files, fileList) { this.$message({ type: 'error', message: '上传文件的数量超出最大限制' }) }, uploadFile(file, fileList) { //重写element的请求 把图片的数据添加到this.formDate this.formDate.append('file', file.file); return false; }, } } </script> <style> </style>
后台代码:
再app.js中写入
var multer = require('multer') app.use(express.static(path.join(__dirname, 'uploads')));//设置express的静态目录 app.use(multer({dest:'uploads'}).array('file'));//设置接收的图片,这里的file要与前端的name一直
upload.js代码
var express = require('express'); var router = express.Router(); var app = express(); var fs=require("fs") var app = express() //设置文件保存路径 router.post('/add', function(req, res, next) { console.log(req.files); console.log(req.body) for(let i=0;i<req.files.length;i++){ var file=req.files[i]; var oldPath = "uploads/"+file.filename; var newPath = "uploads/"+file.filename +".jpg"; var result=fs.renameSync(oldPath,newPath); if(result==undefined){ if(i==req.files.length-1){ console.log(__dirname+newPath) res.json({ status:0, msg:'所有图片上传成功' }) return false; } } } }); /* GET users listing. */ router.get('/', function(req, res, next) { console.log(req) res.json({ msg:'请求成功' }) }); module.exports = router;
差不多花了一天的时候才搞定多图上传与单图上传,这次菜的坑有几个,下面一个一个的说下:
以'Content-Type': 'multipart/form-data'格式发送的数据,express需要使用插件才能解析,我这里使用的是multer
先引入multer插件
var multer = require('multer')
然后use一下,相当于扩展,dest设置文件上传后存放的文件夹,array接收那些数据,这里的file需要与表单中的name属性一直,后面的2代表最多接收2张图片
var paths='uploads/images'; app.use(multer({dest:paths}).array('file',2));
然后就可以在req.files获取以formData格式的数据,既然说到了multipart/form-data,下面就说下fromData对象的作用以及用法
FormData
接口提供了一种表示表单数据的键值对的构造方式
H5 FormData对象就模拟一个原始的表单格式的数据,以前上传文件非得要用个form包起来,就是和后台约定的一个传输数据格式,
FormData就是按照规定的格式,把form中所有表单元素的name与value组装成一个queryString,省去你手工拼接的工作,如果用
过jquery的话,应该知道有个表单序列号的函数,作用和它是一样的,不过FormData还提供了更多的操作方法,全部在原型中,自己本身没任何的属性及方法。
formData文档地址:https://developer.mozilla.org/zh-CN/docs/Web/API/FormData
这次案例使用了append()
这个方法,就是往formData对象中添加额外的数据append(key,value)
第二个坑就是element的上传,先禁用element的自动上传
:auto-upload="false"
element的多图上传,你会发现点击提交是你上传了几个图片就发送了几次请求,这个坑有点尴尬,在接受数据的时候,导致每次只能收到一个,到最后看了下NetWork才发现,然后element提供了
http-request 覆盖默认的上传行为,可以自定义上传的实现
那么就需要我们把默认发送的数据重新写,在标签中写入
:http-request="uploadFile"
methods中写入:
uploadFile(file, fileList) { //重写element的请求 把图片的数据添加到this.formDate this.formDate.append('file', file.file); return false; },
这一步可能大家有点疑惑,因为并没有定义this.formDate,别急往下看
在提交数据按钮的事件中写入:
//提交数据 submitForm(formName) { this.$refs[formName].validate((valid) => { if(valid) { //new 一个FormData对象,uploadFile事件会把把图片的数据添加到this.formDate this.formDate = new FormData() this.$refs.upload.submit(); //添加额外的数据 this.formDate.append('companyname', this.ruleForm.companyname); this.formDate.append('source', this.ruleForm.source); this.formDate.append('names', this.ruleForm.names); this.formDate.append('phone', this.ruleForm.phone); this.formDate.append('mode', this.ruleForm.mode); //设置头部发送格式 let config = { headers: { 'Content-Type': 'multipart/form-data' } } this.$axios.post("/api/company/uploads", this.formDate, config).then(res => { console.log(res) }).catch(res => { console.log(res) }) } else { console.log('error submit!!'); return false; } });
再点击提交的时候先new 一个formData对象,this.$refs.upload.submit()这句代码其实也就是执行了uploadFile这个事件,把图片的数据添加进fromData中,然后再把你其他的数据一一append进去,其次一定要设置头部信息multipart/form-data,因为我们需要发送图片
这就是以fromData的形式发送的数据信息,每个file代表一个图片信息
以上是此次案例的一些难点,回头想想刚开始踩坑的时候,有点难受
发表评论
侧栏公告
寄语
譬如朝露博客是一个分享前端知识的网站,联系方式11523518。
热评文章
标签列表
热门文章
友情链接