前提
这个模块功能是作为一个插件使用在某系统上的,所以没有搭建vue cli来写。使用到的是vue,js+element.js+element.css+jq.js+ajax。
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
文件上传界面是点击一个按钮弹出一个iframe出来的(作为一个模块功能使用)。刚打开是这样的:
点击选取文件按钮选好文件后:
具体代码:
index.html:
<div class="fileBox">
<div class="title">文件上传</div>
<el-upload class="upload-demo" action="/#" :limit="6" :before-upload="morebeforeupload" multiple>
<el-button type="success" size="small" plain class="fileSel" @click="fileSel">选取文件</el-button>
</el-upload>
<el-button class="upSub" type="primary" size="small" @click="onSubmitMore" :icon="iconFile"
style="margin-left: 10px;">
确定上传</el-button>
<p v-if="please" class="please">请点击选取文件按钮选择要上传的文件!</p>
<ul v-for="(item ,i) in fileList" class="el-upload-list el-upload-list--text">
<li>{{i+1}}:<span class="fileRow"><i class="el-icon-document"></i> <input class="nameInp" type="text"
v-model="item.name" /> <i class="el-icon-edit-outline"></i><input class="desInp"
v-model="item.fileDescription" type="text" placeholder="请输入文件描述" /></span>
<el-select size="mini" v-model="item.value" placeholder="请选择文件种类">
<el-option v-for="itemOpt in options" :key="itemOpt.value" :label="itemOpt.label" :value="itemOpt.value">
</el-option>
</el-select><i class="el-icon-close del" @click="del(item.file,i)"></i>
</li>
</ul>
</div>
js部分:
new Vue({
el: '#app',
data: function () {
return {
moreFile: new FormData(),//传到接口的文件数据
iconFile: 'el-icon-folder-add',//确定上传文件的按钮图标
fileList: [],//存放要上传文件的数据
please: true,
options: [{//下拉框的选择
value: '选项1',
label: '身份证复印件'
}, {
value: '选项2',
label: '路段图'
}, {
value: '选项3',
label: '装修准确图'
}, {
value: '选项4',
label: '店租合同'
}, {
value: '选项5',
label: '营业执照'
}],
value: ''//最后选中的下拉框数据
}
},
methods: {
// 点击选择上传文件前,先检查原先是否有文件存在
fileSel: function () {
// this.reset();//每次点击前先置空,不执行这一步的话是叠加上传文件
},
//删除某一行待上传文件
del: function (item, index) {
if (this.fileList.length < 1) {
this.please = true;
}
this.fileList.splice(index, 1)
},
// 阻止文件默认上传,先把数据存到数组里
morebeforeupload: function (file) {
this.please = false;
this.fileList.push({
name: file.name,
file: file,
fileDescription:''
});
return false;
},
// 多文件上传
onSubmitMore: function () {
var that = this;
if (this.fileList.length > 0) {
this.$confirm('请确定是否要上传' + this.fileList.length + '个文件?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(function () {
for (var i = 0; i < that.fileList.length; i++) {
that.moreFile.append('multipartFile', that.fileList[i].file);//这边传什么参数都是在fileList里,根据自己需求传
}
that.iconFile = 'el-icon-loading';
that.upAJAX(this.moreFile);
}).catch(function () {
return;
});
}
},
// 文件上传的其他参数
fileUpCode: function () {
var json = {
'id': getUrlData('id'),
}
return json;
},
// 文件上传ajax
upAJAX: function (data) {
var that = this;//因为是Html的,在ajax 中this指向变了,所以这边定义一个新的参数存this
$.ajax({
url: 'url',
type: "POST",
data: data,//会加到URL后面,必须键值对形式
processData: false, // 告诉jquery不要处理发送的数据
contentType: false, // 告诉jquery不要设置content-Type请求头
success: function (res, textStatus) {
that.reset();//不管上传成功还是不成功都清空数据
if (res.errcode == 0) {//文件上传成功
that.$message({
message: "上传文件成功",
type: "success",
});
} else {
that.$alert("文件上传失败!错误原因为:" + res.errmsg);
}
}, error: function (xhr, status, error) {//XMLHttpRequest对象、错误信息、捕获的错误对象
that.reset();
that.$alert("文件上传失败!错误原因为:" + error);
}
})
},
// 文件上传或失败后执行的清空数据
reset: function () {
this.iconFile = 'el-icon-folder-add';
this.moreFile = new FormData();
this.fileList = [];
this.please = true;
}
}
})
实现逻辑
1:先画出页面
2:定义一个空数组fileList,在elementupload中的:before-upload(file)中将文件push进fileList,这样就能展示出即将上传什么文件。方法中的file是要上传文件的一些参数信息。
3:做待上传文件删除功能,其实就是删除数组fileList中的某条元素。具体看上面的代码。
4:整理要传给后端的数据。定义一个moreFile:new FormData()。一定要记得是new FormData()。然后将fileList数组中的file等数据循环append进moreFile。
5:上传文件ajax具体参数要跟后端对接好。
注意:
1:先要弄清楚:vule和v-model区别,原先文件名称输入框的v-model我写成了:vule,bug就是修改文件名称输入框内容,再去修改描述输入框内容时,文件名称输入框自动变成了原先定义的文件名称(实现不了自定义文件名称的功能)。解决办法是使用v-model代替:value.
2:改一个文件的描述,其他文件的描述一起变:描述输入框v-model绑定的item.fileDescription在fileList中是没有定义这个字段的(查看上面的代码就知道fileList定义的是[]空数组)。导致我改一个描述,其他描述都是一起变。解决方法是在文件上传前push fileList数组时,定义空的fileDescription。
3:input一次只能输入一个字符:还是这两个控件的问题,发现描述框输入一个字符串光标就出去了,就是输一个字符串,还得用鼠标点击进描述输入框才能写,每次只能输入一个字。解决办法是删掉描述控件中的:key=“item.fileDescription”。我其实到现在都还不知道为什么这个bug是这个问题,明明key只是个标识而已。(偷偷懵逼,主要还是自己技术不行,对vue还不够熟练)。
4:element文件支持多文件上传,但是内部还是一个一个文件上传的。从 :before-upload这个方法就可以看出。
5:ajax参数上传的时候一直有问题,报错是格式不对,后面发现ajax参数要重点设置下processData,contentType这两个。具体看代码。
以上实现文件上传功能还是花费了挺多时间的,主要是因为自己对Vue还不够了解。哎呀呀,代码好难!!!哭了~~~