在前端项目中,附件上传是很常用的功能,几乎所有的app相关项目中都会使用到,一般在选择使用某个前端UI框架时,可以查找其内封装好的图片上传组件,但某些情况下可能并不适用于自身的项目需求,本文中实现的附件上传区域支持超多类型附件分类型上传,并且可根据特定条件具体展示某些类型的附件上传,本文中是直接摘自具体的页面,后面会抽时间单独封装出来一个附件上传的组件。

一、Vue页面内附件展示区域代码

 1 <div class="retuinfo">
2 <div class="theadInfo-headline">
3 <span></span>
4 {{FileDivName}}
5 </div>
6 <Collapse v-model="defaultCollapse">
7 <Panel v-for="(item,pngIndex) in pngFileArray" v-bind:key="pngIndex" :name="item.num" v-show="item.isshow">
8 {{item.name}}
9 <div class="obsfilesdiv" slot="content">
10 <div v-for="(obs,index) in item.files" v-bind:key="index" class="obsfileslist">
11 <input ref="fileImg" type="file" accept="image/*;capture=camera" style="display: none;"
12 @change="setObsFile(item.num,1,obs.FileType,obs.Num,obs.Code)">
13 <label style="color:#6d7180; font-size: 20px;">{{obs.FileType}}<span style="color:red;"
14 v-show="obs.FileType!='其他'">*</span></label>
15 <ul class="obsfilesul">
16 <li v-for="(objitem,objindex) in obs.FileObj" v-bind:key="objindex">
17 <img :src="objitem.imgurl ? objitem.imgurl : fileUrl"
18 @click="showObsFiles(obs.FileFlag,objitem.imgurl)" />
19 <img src="../../../img/other/wrong.png" v-show="objitem.IsCanEdit" class="wrong_class"
20 @click="deleteObsFlie(item.num,index,objindex,objitem.imgid,objitem.imgurl)" />
21 </li>
22 <li style="border: 4px solid #f3f3f3;" @click="PlusClick(obs.FileType,obs.FileFlag,obs.Num)">
23 <img src="../../../img/icon-adds.png" alt="" />
24 </li>
25 <div style="clear:both;"></div>
26 </ul>
27 </div>
28 </div>
29 </Panel>
30 </Collapse>
31 </div>
32 <div class="modal" v-show="viewBigImg">
33 <div class="img-view-modal" style="text-align: right;">
34 <img :src="viewImgURL" style="width: 100%;" @click="hideShow(0)">
35 <Icon type="md-close" style="margin-right: 20px;" size='20' @click="hideShow(0)" />
36 </div>
37 </div>
38 </div>
Vue项目引入了以下UI框架:(若想拿来即用 需要先在main.js中引入)
IView、MintUI、Vant 此段代码只要确保引入IView即可正常使用

二、数据绑定设计

具体的不详细展开说,数组与通过属性控制,很好理解。

pngFileArray: [{
num: '0',
name: '整车',
isshow: localStorage.getItem("RoleName").indexOf('铭牌质检员') != -1 ? true : false,
files: [ //FileFlag://1:图片;2:视频 3.其他
{
FileType: '整车铭牌图片',
Code: '201',
Num: 0,
FileFlag: 1,
FileObj: [],
IsNoFile: true
},
{
FileType: '车架VIN图片',
Code: '207',
Num: 1,
FileFlag: 1,
FileObj: [],
IsNoFile: true
},
{
FileType: '终端图片',
Code: '301',
Num: 2,
FileFlag: 1,
FileObj: [],
IsNoFile: true
}
]
},
{
num: '1',
name: '里程',
isshow: localStorage.getItem("RoleName").indexOf('客户经理') != -1 ? true : false,
files: [{
FileType: '里程表照片',
Code: '701',
Num: 3,
FileFlag: 1,
FileObj: [],
IsNoFile: true
}
]
}
],

三、绑定的方法

1.图片加载方法:

 1 //获取图片列表
2 getImageList() {
3 this.$indicator.open({
4 text: '图片加载中...',
5 spinnerType: 'snake'
6 });
7 let _this = this;
8 let downRequest ={
9 'crm_vin': this.parms.crm_vin,
10 'crm_vehiclenumber': this.parms.crm_vehiclenumber
11 };
12 let imgListParams = {
13 "ImageDownRequest": JSON.stringify(downRequest),
14 "username": localStorage.getItem("usernameone"),
15 "password": localStorage.getItem("password")
16 };
17 console.log("获取图片列表参数:", imgListParams);
18 _this.$ajax.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;'; //配置请求头
19 this.$ajax.post(this.imageListUrl, this.$qs.stringify(imgListParams)).then(resdata => {
20 _this.$indicator.close();
21 console.log("获取到的图片列表数据:", resdata);
22 let data = resdata.data;
23 console.log("转换后的图片列表数据:", data);
24 if (resdata.status != 200) {
25 _this.$toast({
26 message: '获取图片列表失败!',
27 duration: 3000
28 });
29 return;
30 }
31 //先清空原有的图片列表
32 _this.pngFileArray.forEach((rr,index,array) =>{
33 for(var file=0;file<rr.files.length;file++){
34 _this.pngFileArray[index].files[file].FileObj = [];
35 _this.pngFileArray[index].files[file].IsNoFile = true;
36 }
37 });
38 //将图片列表写入页面各图片分类区域
39 for(var i=0;i<data.length;i++){
40 _this.pngFileArray.forEach((rr,index,array) =>{
41 for(var file=0;file<rr.files.length;file++){
42 if(data[i].crm_imagetypeno==rr.files[file].Code){
43 let putparm = {
44 "IsCanEdit":false,
45 "imgid": data[i].crm_careimageId,
46 "imgurl": data[i].ImageUrl
47 };
48 _this.pngFileArray[index].files[file].FileObj.push(putparm);
49 _this.pngFileArray[index].files[file].IsNoFile = false;
50 }
51 }
52 });
53
54 }
55 }).catch(function(error) {
56 _this.$indicator.close();
57 _this.$toast({
58 message: error,
59 duration: 3000
60 });
61 });
62 },

2.图片展示方法

showObsFiles(type, url) { //展示图片或视频
console.log("展示附件:" + type);
if (type == 1) { //图片
this.viewBigImg = true;
this.viewImgURL = url;
} else { //文件
this.$messagebox.alert("不支持查看文件,请到PC端操作!", "提示");
return;
}
},

3.上传图片相关方法

(最开始设计的是支持图片、视频和其他类型文件等上传,项目中已实现,本文中不做拓展)

  1 PlusClick(type, flag, num) {
2 console.log("当前附件类型:" + type);
3 console.log("当前附件序号:" + num);
4 this.currentFileType = type;
5 if (flag == 1) { // 图片上传
6 this.$refs.fileImg[num].dispatchEvent(new MouseEvent('click'));
7 } else if (flag == 2) { // 视频上传
8 this.$refs.fileVideo[num].dispatchEvent(new MouseEvent('click'));
9 } else { // 其他类型文件
10 this.$refs.filElem[num].dispatchEvent(new MouseEvent('click'));
11 }
12 },
13 setObsFile(classify, type, obsFileType, num, code) { //保存图片到crm中
14 var _this = this;
15 var inputFile; //文件流
16 console.log("图片大分类:" + classify + " " + obsFileType + " " + num) + " 图片编码:" + code;
17 if (type == 1) {
18 inputFile = this.$refs.fileImg[num].files[0];
19 this.$refs.fileImg[num].value = '';
20 }
21 var fileName = inputFile.name;
22 if (!inputFile) {
23 return;
24 }
25 if (inputFile.type == 'image/jpg' || inputFile.type == 'image/jpeg' || inputFile.type == 'image/png' ||
26 inputFile.type ==
27 'image/gif') {} else {
28 this.$messagebox.alert("请上传图片", "提示");
29 return;
30 }
31 _this.$indicator.open({
32 text: '文件上传中,请稍候...',
33 spinnerType: 'snake'
34 });
35 //图片压缩与转换成base64文件流
36 var reader = new FileReader();
37 reader.readAsDataURL(inputFile);
38 reader.onloadend = function(e) {
39 let result = this.result;
40 console.log('********未压缩前的图片大小******** :' + result.length / 1024)
41 _this.pulic.dealImage(result, {}, function(base64) {
42 console.log('********压缩后的图片大小******** :' + base64.length / 1024)
43 _this.putObsFile(classify, fileName, base64, obsFileType, code);
44 });
45 //reader.result.substring(this.result.indexOf(',')+1);
46 // 'data:image/png;base64,'+reader.result
47 }
48 },
49 putObsFile(classify, fileName, base64, obsFileType, code) { //抽出公共上传图片文件方法
50 var _this = this;
51 let usernameone = this.$Base64.encode("administrator");
52 let password = this.$Base64.encode("pass@word1");
53 let parmsImages = {
54 crm_newenergyid: localStorage.getItem("crm_newenergyid"),
55 vin: _this.parms.crm_vin,
56 crm_vehiclenumber: _this.parms.crm_vehiclenumber,
57 CareType: code,
58 CreateBy: localStorage.getItem("SystemUserId"),
59 ImageStr: base64.split(",")[1],
60 username: usernameone,
61 password: password
62 }
63 let parms = {
64 ImageMessage: JSON.stringify(parmsImages)
65 }
66 console.log(JSON.stringify(parmsImages));
67 console.log(JSON.stringify(parms));
68 _this.$ajax.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;'; //配置请求头
69 _this.$ajax.post(_this.imageSaveUrl, _this.$qs.stringify(parms))
70 .then(resdata => {
71 _this.$indicator.close();
72 console.log("接口响应数据:", resdata);
73 let data = resdata.data;
74 console.log("转换后的响应数据:", data);
75 if (resdata.status != 200) {
76 _this.$toast({
77 message: '保存失败!接口调用异常',
78 duration: 3000
79 });
80 return;
81 }
82 //将上传成功后的图片url回写到页面的图片分类url中
83 console.log("当前分类下的所有图片类型:" + JSON.stringify(_this.pngFileArray[parseInt(classify)].files));
84 for (var i = 0; i < _this.pngFileArray[parseInt(classify)].files.length; i++) { //遍历当前分类下的图片类型数组 并赋值后台返回的数据
85 if (obsFileType == _this.pngFileArray[parseInt(classify)].files[i].FileType) {
86 //设置图片文件路径等 putparm
87 let putparm = {
88 "IsCanEdit":true,
89 "imgid": data.crm_careimageId,
90 "imgurl": data.ImageUrl
91 };
92 _this.pngFileArray[parseInt(classify)].files[i].FileObj.push(putparm);
93 _this.pngFileArray[parseInt(classify)].files[i].IsNoFile = false;
94 }
95 }
96 _this.$messagebox.alert("附件上传成功", "提示");
97 }).catch(err => {
98 console.log(JSON.stringify(err));
99 _this.$toast({
100 message: '上传失败',
101 duration: 1500
102 });
103 _this.$indicator.close();
104 });
105 },

4.删除图片方法

(本文中是只有未提交的图片可删除,若已提交过的图片即页面初始加载获取到的图片不可以删除)

 1 deleteObsFlie(classify,num,index,id,url) { //删除附件
2 var _this = this;
3 this.$messagebox.confirm('确定删除该图片吗?', "确认").then(action => {
4 var del_param = {
5 "id": id,
6 "url": url
7 };
8 _this.$indicator.open({
9 text: '删除图片中,请稍候...',
10 spinnerType: 'snake'
11 });
12 _this.$ajax.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;'; //配置请求头
13 _this.PromiseCall(_this.DelImgFilesURL, _this.$qs.stringify(del_param))
14 .then(data => {
15 _this.$indicator.close();
16 console.log(JSON.stringify(data));
17 if (data.status != 200) {
18 _this.$messagebox.alert("删除图片失败", "提示");
19 return;
20 }
21 _this.pngFileArray[parseInt(classify)].files[num].FileObj.splice(index, 1);
22 _this.$toast({
23 message: '删除图片成功',
24 duration: 1500
25 });
26 }).catch(err => {
27 _this.doCatch(err);
28 _this.$toast({
29 message: '删除图片失败'+err,
30 duration: 1500
31 });
32 _this.$indicator.close();
33 });
34 });
35 },

四、CSS样式

.retuinfo {
width: 96%;
height: auto;
margin-top: 20px;
margin-left: 2%;
background-color: #F5F7FA;
border-radius: 15px;
}
.theadInfo-headline {
width: 100%;
height: 80px;
background: #F3F3F3;
display: flex;
padding-left: 30px;
align-items: center;
font-size: 28px;
color: #666666;
border-radius: 15px;
}
.theadInfo-headline span {
width: 6px;
height: 32px;
background: #5576AB;
border-radius: 3px;
margin-right: 10px;
}
.ivu-collapse-header {
height: 40px;
align-items: center;
display: flex;
}
.obsfilesdiv {
width: 100%;
height: auto;
margin-top: .5rem;
margin-bottom: 50px;
}
.obsfileslist {
width: 100%;
height: auto;
padding: 0.5rem 0.5rem;
background: #fff;
}
.obsfilesul {
width: 100%;
height: auto;
padding-bottom: 8px;
}
.obsfilesul li {
width: 120px;
height: 120px;
float: left;
margin-top: .3rem;
overflow: hidden;
margin-right: .3rem;
border: none;
}
.obsfilesul li img {
width: 100%;
height: 100%;
}
.imglist {
width: 100%;
margin-top: .5rem;
margin-bottom: 6rem;
}
.modal {
background-color: #A9A9A9;
position: fixed;
z-index: 99;
left: 0;
top: 0;
width: 100%;
height: 100%;
padding-top: 4rem;
/*opacity: 0.5;*/
align-items: center;
/*定义body的元素垂直居中*/
justify-content: center;
/*定义body的里的元素水平居中*/
}
.modal img {
animation-name: zoom;
animation-duration: 0.6s;
display: block;
padding: 10px;
margin: auto;
max-width: 100%;
max-height: 100%;
box-shadow: 0 2px 6px rgb(0, 0, 0, 0), 0 10px 20px rgb(0, 0, 0, 0);
border-radius: 12px;
border: 1px solid white;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.showname {
width: 100px;
height: 60px;
position: relative;
top: -4.5rem;
white-space: normal;
word-break: break-all;
word-wrap: break-word;
}
.wrong_class {
width: 30% !important;
height: 30% !important;
position: relative;
top: -3.8rem;
left: 2.6rem;
}
.wrongs_class {
width: 4% !important;
height: 4% !important;
position: relative;
/*top: -5.2em;*/
left: 0.5rem;
}

最后附上实际效果图:

Vue页面内公共的多类型附件图片上传区域并适用折叠面板的更多相关文章

  1. 基于前台vue,后台是spring boot的压缩图片上传

    本人是刚毕业的新手,最近公司的一个项目,前后端分离,前端Vue,后端使用spring boot.其中有一个需求是需要做前端上传的图片需要压缩才能上传.为此在网上查找资料,并做了简单的实现. 那么一步来 ...

  2. wordpress 图片上传冲突

    网上常见的wordpress图片上传 jQuery('#upload_image_button').click(function() { //formfield并未用上,可能代码遗漏了一段,怀疑和类的 ...

  3. JavaScript实现本地图片上传预览功能(兼容IE、chrome、FF)

    需要解决的问题有:本地图片如何在上传前预览.编辑:最近发现这个功能很多是基于flash实现的,很多JavaScript实现的代码兼容性都很差,特别是在IE和firefox和chrome三个浏览器上不兼 ...

  4. 在php中使用jquery uploadify进行多图片上传

    jquery uploadify是一款Ajax风格的批量图片上传插件,在PHP中使用jquery uploadify很方便,请按照本文介绍的方法和步骤,为你的PHP程序增加jquery uploadi ...

  5. summernote(富文本编辑器)将附件与图片上传到自己的服务器(vue项目)

    1.上传图片至自己的服务器(这个官方都有例子,重点介绍附件上传)图片上传官方网址 // onChange callback $('#summernote').summernote({ callback ...

  6. 用Vue来实现图片上传多种方式

    没有业务场景的功能都是耍流氓,那么我们先来模拟一个需要实现的业务场景.假设我们要做一个后台系统添加商品的页面,有一些商品名称.信息等字段,还有需要上传商品轮播图的需求. 我们就以Vue.Element ...

  7. php 图片上传的公共方法(按图片宽高缩放或原图)

    写的用于图片上传的公共方法类调用方法: $upload_name='pic';$type = 'logo_val';$file_name = 'logo_' . $user_id .create_st ...

  8. 后台管理系统之“图片上传” --vue

    图片上传(基于vue) 相信上传图片是所有系统必备的功能吧,工作中的第一个管理系统就在上传图片的功能上卡顿了一整天. 当时用的elementUI组件,但是由于样式和设计图样式差别较大再加上原生相较好理 ...

  9. vue+axios实现移动端图片上传

    在利用vue做一些H5页面时,或多或少会遇到有图片上传的操作,主要是运用html5里面的input[type=file]来实现,传递到后端的数据是以二进制的格式传递,所以上传图片的请求与普通的请求稍微 ...

随机推荐

  1. 更通俗的理解JS原型链

    最近在网上看到一篇理解原型链的,感觉非常好非常通俗易懂,拿来记录一下~: 1)人是人他妈生的,妖是妖他妈生的.人和妖都是对象实例,而人他妈和妖他妈就是原型.原型也是对象,叫原型对象. 2)人他妈和人他 ...

  2. 洛谷 P6914 - [ICPC2015 WF]Tours(割边+找性质)

    洛谷题面传送门 神仙题. 深夜写题解感受真好 我们考虑两个简单环 \(C_1,C_2\)​​​,我们假设颜色种类数为 \(k\)​​​,那么我们需要有 \(C_1,C_2\)​​​ 均符合条件,而由于 ...

  3. snakmake 小练习

    最近在学习snakemake 用于生信流程管理,现在用一个snakemake 来完成小任务:将在某一文件夹下的多个bam文件截取一部分,然后建立索引,在提取出fastq序列,最后比对回基因组. 需要两 ...

  4. Java 读取txt文件生成Word文档

    本文将以Java程序代码为例介绍如何读取txt文件中的内容,生成Word文档.在编辑代码前,可参考如下代码环境进行配置: IntelliJ IDEA Free Spire.Doc for Java T ...

  5. Django结合Echarts在前端展示数据

    前言 最近在用Django写UI自动化测试平台,基本快要弄完了,但是首页只有项目列表展示,一直感觉很空旷,所以想把一些关键数据在首页展示出来. 这时就想到利用Echarts这个开源项目,但是Djang ...

  6. ubuntu18.10搜狗输入法的安装

    记录一下 1.卸载ibus ubuntu默认使用ibus管理输入法,官方推荐使用fcitx.我们先卸载ibus sudo apt-get remove ibus 清除ibus配置,如果没有设置 sud ...

  7. 容器之分类与各种测试(三)——stack

    stack是栈,其实现也是使用了双端队列(只要不用双端队列的一端,仅用单端数据进出即完成单端队列的功能),由于queue和stack的实现均是使用deque,没有自己的数据结构和算法,所以这俩也被称为 ...

  8. JAXB—Java类与XML文件之间转换

    JAXB-Java类与XML文件之间转换 简介         JAXB(Java Architecture for XML Binding) 是一个业界的标准,是一项可以根据XML Schema产生 ...

  9. [学习总结]1、View的scrollTo 和 scrollBy 方法使用说明和区别

    参考资料:http://blog.csdn.net/vipzjyno1/article/details/24577023 非常感谢这个兄弟! 先查看这2个方法的源码: scrollTo: 1 /** ...

  10. Output of C++ Program | Set 8

    Predict the output of following C++ programs. Question 1 1 #include<iostream> 2 using namespac ...