在前端项目中,附件上传是很常用的功能,几乎所有的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. jmeter链接数据库,信息全部填写正确,运行之后没有结果

    之前遇到一个很苦恼的问题,jmeter链接数据库,数据库填写的资料全部都没有问题,在其他电脑jmeter上都可以正常链接,但是在我的电脑上运行却总是不出结果, 用mysql链接数据库也一切正常,一直找 ...

  2. uniapp中vuex的基本使用

    1. 创建一个uniapp项目 2. 在项目目录下用npm安装 vuex npm install vuex --save 3. 在项目根目录下创建 store文件夹,在store文件夹中创建 inde ...

  3. 洛谷 P7163 - [COCI2020-2021#2] Svjetlo(树形 dp)

    洛谷题面传送门 神仙级别的树形 dp. u1s1 这种代码很短但巨难理解的题简直是我的梦魇 首先这种题目一看就非常可以 DP 的样子,但直接一维状态的 DP 显然无法表示所有情况.注意到对于这类统计一 ...

  4. Generic recipe for data analysis with general linear model

    Generic recipe for data analysis with general linear model Courtesy of David Schneider State populat ...

  5. Web网页服务器软件——介绍

    Web网页服务器软件与硬件服务器的关系,就像软件和电脑的关系. 目前有,世界使用排列第一名的Apache.还有可以在Linux系统下快速方便地搭建出LNMP Web服务环境的Nginx(其中LNMP分 ...

  6. 如何利用官方SDK文件来辅助开发

    如何利用官方SDK文件来辅助开发 1.首先要先知道什么是SDK? SDK或者SDK包指的是,半导体厂商针对自己研发的芯片,同步推出的一个软件开发工具包. 它可以简单的为某个程序设计语言提供应用程序接口 ...

  7. Kubernetes-存储(一)

    前言 本篇是Kubernetes第十二篇,大家一定要把环境搭建起来,看是解决不了问题的,必须实战. Kubernetes系列文章: Kubernetes介绍 Kubernetes环境搭建 Kubern ...

  8. Ubuntu apt代理apt-cacher-ng配置及使用

    apt-cacher-ng是更强大的apt代理服务器的替代方案,例如squid-deb-proxy.如果您正在运行小型家庭或办公室网络,那就别无所求.它可能缺少一些更高级的功能,但是可以立即进行配置, ...

  9. Windows cmd 命令行基本操作

    Windows cmd 命令行基本操作 1. 进入到指定根目录 注意:不区分大小写 例如进入到 D 盘 2. 进入到指定的目录 例如 (如果目录文件名太长,可以使用 tab 键来自动补全.重复按可以进 ...

  10. Elasticsearch中关于transform的一个问题?

    背景:现在有一个业务,派件业务,业务员今天去派件(扫描产生一条派件记录),派件可能会有重复派件的情况,第二天再派送(记录被更新,以最新的派件操作为准).现在需要分业务员按天统计每天的派件数量.es版本 ...