欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-07-22 16:26:43
注意:input[type="file"] 标签中的属性accept="application/msword,application/pdf" 在pc上正常,但是在手机io...

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

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

```

<template>
<div id="my-careers">
<head-top id="header">
<i slot="left" class="iconfont icon-back"></i>
<span slot="title">apply online</span>
<i slot="right" class="icon-right fa"></i>
</head-top>
<div class="content">
<form @submit.prevent="onsubmit" id="fileform" >
<div class="form">
<h3>customer car manager</h3>
<ul class="form-group">
<li class="info-name">
<input type="text" v-focus :class="{errli:form.nameerr}" name="name" placeholder="name" v-model="applyinfo.name" >
<p class="errp" v-if="form.nameerr">{{form.namemsg}}</p>
</li>
<li class="info-email">
<input type="text" :class="{errli:form.emailerr}" name="email" placeholder="email address" v-model="applyinfo.email" >
<p class="errp" v-if="form.emailerr">{{form.emailmsg}}</p>
</li>
<li class="info-mobile">
<input type="number" :class="{errli:form.mobileerr}" name="mobile" placeholder="mobile number" v-model="applyinfo.mobile" >
<p class="errp" v-if="form.mobileerr">{{form.mobilemsg}}</p>
</li>
<li class="info-location">
<input type="text" :class="{errli:form.locationerr}" name="location" placeholder="current location" v-model="applyinfo.location" >
<p class="errp" v-if="form.locationerr">{{form.locationmsg}}</p>
</li>
<li class="reason-li" :class="{'info-reason':applyinfo.joinreason.split('').length >= 300}">
<textarea :class="{errli:form.joinreasonerr}" name="joinreason" v-model="applyinfo.joinreason" rows="5" cols="20" placeholder="why do you want to join happyeasy go?" ></textarea>
<span>{{wordnumber}}</span>
<p class="errp" v-if="form.joinreasonerr">{{form.joinreasonmsg}}</p>
</li>
<li class="info-link">
<input type="text" :class="{errli:form.linkedinurlerr}" name="linkedinurl" placeholder="linkedin url (optional)" v-model="applyinfo.linkedinurl" >
<p class="errp" v-if="form.linkedinurlerr" >{{form.linkedinurlmsg}}</p>
</li>
<li class="info-file" >
<span class="file-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" id="upfile" accept="application/msword,application/pdf" name="upfile" @change="selectfile" ><span>upload file</span> or drag and drop</p>
</li>
<li class="info-btns flex space-between" >
<button @click="infojustify" :class="{active:true}">submit</button>
</li>
</ul>
</div>
</form>
</div>
<div class="career-cover" v-show="showdialog"></div>
<div class="career-dialog" v-show="showdialog">
<div class="d-top">
apply online
</div>
<div class="d-center">
thank you for applying to this job!
</div>
<div class="d-bottom">
<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>

总结

以上所述是小编给大家介绍的vue中使用input[type="file"]实现文件上传功能,希望对大家有所帮助