vue中使用input[type="file"]实现文件上传功能

注意:input[type="file"] 标签中的属性accept="application/msword,application/pdf" 在pc上正常,但是在手机ios和android上这个文件格式限制会被忽略,所以需要在js中增加格式的判断,以及对应显示样式的设置.(我也是刚发现,如果有遇到这个问题的可以参考下---下面有更改:)

vue中使用input[type="file"]实现文件上传功能

```

<template> <div> <head-top> <i slot="left"></i> <span slot="title">Apply Online</span> <i slot="right"></i> </head-top> <div> <form @submit.prevent="onSubmit" > <div> <h3>Customer Car Manager</h3> <ul> <li> <input type="text" v-focus :class="{errli:form.nameErr}" placeholder="Name" v-model="applyInfo.name" > <p v-if="form.nameErr">{{form.nameMsg}}</p> </li> <li> <input type="text" :class="{errli:form.emailErr}" placeholder="Email Address" v-model="applyInfo.email" > <p v-if="form.emailErr">{{form.emailMsg}}</p> </li> <li> <input type="number" :class="{errli:form.mobileErr}" placeholder="Mobile Number" v-model="applyInfo.mobile" > <p v-if="form.mobileErr">{{form.mobileMsg}}</p> </li> <li> <input type="text" :class="{errli:form.locationErr}" placeholder="Current Location" v-model="applyInfo.location" > <p v-if="form.locationErr">{{form.locationMsg}}</p> </li> <li :class="{'info-reason':applyInfo.joinReason.split('').length >= 300}"> <textarea :class="{errli:form.joinReasonErr}" v-model="applyInfo.joinReason" rows="5" cols="20" placeholder="Why do you want to join HappyEasy Go?" ></textarea> <span>{{wordNumber}}</span> <p v-if="form.joinReasonErr">{{form.joinReasonMsg}}</p> </li> <li> <input type="text" :class="{errli:form.linkedinUrlErr}" placeholder="LinkedIn URL (Optional)" v-model="applyInfo.linkedinUrl" > <p v-if="form.linkedinUrlErr" >{{form.linkedinUrlMsg}}</p> </li> <li > <span v-if="fileObj != null" v-show="isSelectFile">{{fileObj.name}}</span> <p v-show="!isSelectFile">Attach Resume</p> <p v-show="!isSelectFile">(Microsoft Word or PDF file is allowed (5MB))</p> <p><input type="file" accept="application/msword,application/pdf" @change="selectFile" ><span>Upload file</span> or drag and drop</p> </li> <li > <button @click="infoJustify" :class="{active:true}">Submit</button> </li> </ul> </div> </form> </div> <div v-show="showDialog"></div> <div v-show="showDialog"> <div> Apply Online </div> <div> Thank you for applying to this job! </div> <div> <button @click="applySuccess">OK</button> </div> <img :src="dialogBg" alt=""> </div> </div> </template> ``` <script> import {Toast, Indicator} from 'mint-ui'; import { Reg } from '../../models/utils/Reg.js'; import headTop from "Components/head/header.vue"; import { DomainManager } from '../../request/DomainManager'; export default { components:{ headTop, }, data(){ return { arr:[], fileObj:null, showDialog:false, isSelectFile:false, dialogBg:require('../../assets/images/joinus/join-character.png'), applyInfo:{// form表单绑定的数据,linkedinUrl是可选参数 name:"", email:"", mobile:"", location:"", joinReason:"", linkedinUrl:"", positionId:null, departmentId:null, }, form:{// 对应input错误信息的设置 nameMsg:"Please enter a valid name",nameErr:false, emailMsg:"Please enter a valid Email Address",emailErr:false, mobileMsg:"Please enter a valid Mobile Number",mobileErr:false, locationMsg:"Please enter your current location",locationErr:false, joinReasonMsg:"Please write down your reason",joinReasonErr:false, linkedinUrlMsg:"",linkedinUrlErr:false, fileMsg:"Microsoft Word or PDF file is allowed (<5MB)", fileNull:"Please Upload your attach resume", submitFail:"Something's wrong, Please try it again", submitting:"Uploading...Please wait", }, } }, computed:{ wordNumber(){// 动态计算textarea的字数 let number = this.applyInfo.joinReason.split("").length; return (300 - number); } }, watch:{ applyInfo:{// 配合限制textarea的字数 handler:function(val,oldV){ if(this.applyInfo.joinReason.split('').length >= 300){ this.applyInfo.joinReason = this.applyInfo.joinReason.substr(0,300); } if(this.applyInfo.name != ""){ this.form.nameErr = false; } if(this.applyInfo.email != ""){ this.form.emailErr = false; } if(this.applyInfo.mobile != ""){ this.form.mobileErr = false; } if(this.applyInfo.location != ""){ this.form.locationErr = false; } if(this.applyInfo.joinReason != ""){ this.form.joinReasonErr = false; } }, deep:true } }, methods:{ selectFile(){ // 注意这里想要获取formDate的数据格式,那么input必须加上name属性,且name值对应绑定的v-model数据名字 let size; this.fileObj = document.getElementById("upfile").files[0];//获取文件信息 if(this.fileObj){ // 原来的代码,稍作调整 size = (this.fileObj.size / (1024 * 1024)).toFixed(2); let idx = this.fileObj.name.lastIndexOf("."); if (idx != -1){ let ext = this.fileObj.name.substr(idx+1).toUpperCase(); ext = ext.toLowerCase( ); if (ext != 'pdf' && ext != 'doc' && ext !='docx'){ Toast("You can upload.pdf,.doc,.docx files only.") if(this.arr.length >= 1){ this.fileObj = this.arr[0]; }else{ this.isSelectFile = false; } }else{ if(size >= 5){ Toast("Please select files within 5M") if(this.arr.length >= 1){ this.fileObj = this.arr[0]; }else{ this.isSelectFile = false; } }else{ this.arr[0] = this.fileObj; this.isSelectFile = true; } } } }else{// 当打开本地文件,点击取消不选择时,显示已经选择过的文件,如果没有这个if则显示没有文件的状态 if(this.arr.length >= 1){ this.fileObj = this.arr[0]; }else{ this.isSelectFile = false; } } }, infoJustify(){ // 判断input的内容正确与否 if(this.applyInfo.name == ""){ this.form.nameErr = true; }else if(this.applyInfo.email == "" || !Reg.email.test(this.applyInfo.email)){ this.form.nameErr = false; this.form.emailErr = true; }else if(this.applyInfo.mobile == "" || !Reg.ChinaMobile.test(this.applyInfo.mobile)){ this.form.nameErr = false; this.form.emailErr = false; this.form.mobileErr = true; }else if(this.applyInfo.location == ""){ this.form.nameErr = false; this.form.emailErr = false; this.form.mobileErr = false; this.form.locationErr = true; }else if(this.applyInfo.joinReason == ""){ this.form.nameErr = false; this.form.emailErr = false; this.form.mobileErr = false; this.form.locationErr = false; this.form.joinReasonErr = true; }else if(this.fileObj == null){ this.form.nameErr = false; this.form.emailErr = false; this.form.mobileErr = false; this.form.locationErr = false; this.form.joinReasonErr = false; this.form.linkedinUrlErr = false; Toast({ message:"Please select the file", duration:1500 }); }else{ this.fileUpload(); } }, fileUpload(){ //这里是只上传文件的步骤 // let formData = new FormData(); // formData.append("upfile",this.fileObj); // 这里上传文件并且需要传更多参数的时候 let fileForm = document.getElementById("fileForm");// 获取整个form表单数据,记住input都需要name属性 let url = DomainManager.saveCareer();// 上传服务器接口 let params = this.$route.query; let formData = new FormData(fileForm); formData.append("positionId",params.positionId);// 这就是给formData添加新的表单数据的形式 formData.append("departmentId",params.departmentId); this.$axios({ url:url, method:"post", data:formData, headers:{"Content-Type":"multipart/form-data"}, }).then(res => { if(res.success){ this.showDialog = true; }else{ } }).catch(err =>{ console.log(err) }); }, applySuccess(){ this.showDialog = false; }, onSubmit(){ // 取消form表单的自动提交功能 return false; } }, directives:{ focus: { inserted: function (el) { el.focus() } } } } </script> <style lang="less" scoped> #my-careers{ .content{ padding: 0.5rem 0.2rem 0; text-align: left; h3{ font-size:0.16rem; padding: 0.15rem 0; } .form-group{ li{ position: relative; width:100%; margin-bottom:0.24rem; color:#999; display:flex; input,textarea{ width:93.5%; padding:0.09rem 3%; border:1px solid #ddd; border-radius:0.03rem; vertical-align: top; font-size: 0.14rem; } *::placeholder{ color:#999; } } .reason-li{ textarea{font-family: inherit;} span{ position:absolute; font-size:0.14rem; right: 0.05rem; bottom: 0; } } .info-reason{ textarea{resize: none;} } .info-file{ display:block; border:1px dashed #eee; font-size: 0.14rem; text-align: center; padding:0.13rem 0 0.1rem; margin-bottom:0.15rem; height:0.59rem; .file-span{ color:#999; background:#fff; padding:0.02rem 0.1rem; margin-bottom:0.05rem; border:1px solid #ddd; border-radius:3px; box-shadow:0 2px 5px #999; } p{ position: relative; line-height:0.2rem; color:#999; span{ color:#0b9d78; } input{ position: absolute; width:0.66rem; opacity: 0; display:inline-block; padding:0; border:0; } } } .info-btns{ margin-bottom:0; button{ width:2rem; padding:0.06rem 0; font-size: 0.16rem; color:#999; background: #eee; border-radius: 0.03rem; margin:auto; } .active{ color:#fff; background: #ffa000; } } .errli{ border:1px solid #d32f2f; } .errP{ position: absolute; font-size:0.14rem; color:#d32f2f; left: 0; bottom: -0.2rem; padding-left:3%; } } } .career-cover{ width: 100%; height: 100%; position:absolute; top: 0; left: 0; background: rgba(0, 0, 0, 0.5); z-index:10; } .career-dialog{ width:2.8rem; position: absolute; top: 35%; left: 0; right: 0; margin:auto; z-index:11; background:rgba(255, 255, 255, 1); padding:0.3rem 0.2rem; border-radius:5px; overflow: hidden; .d-top{ font-size: 0.14rem; color:#666; display:flex; align-items: center; font-weight: bold; } .d-top::after{ display:block; content:""; flex:1; margin-left:0.15rem; border-top:1px solid #999; } .d-center{ padding:0.3rem 0; color:#0b9d78; font-size: 0.16rem; font-weight: bold; } .d-bottom{ position: relative; height:0.3rem; margin-bottom:0.15rem; button{ position: absolute; width:2rem; padding:0.1rem 0; font-size: 0.16rem; color:#fff; background: #ffa000; border-radius:3px; left: 0; right: 0; margin:auto; z-index:9; } } img{ opacity: 0.2; position:absolute; width:1.8rem; top: 0.5rem; right: -0.1rem; z-index:8; } } } </style>

总结

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/541e2ec6b26381b86d8bf10959c6678c.html