Vue頁面內(nèi)公共的多類型附件圖片上傳區(qū)域并適用折疊面板(示例代碼)
在前端項目中,附件上傳是很常用的功能,幾乎所有的app相關(guān)項目中都會使用到,一般在選擇使用某個前端UI框架時,可以查找其內(nèi)封裝好的圖片上傳組件,但某些情況下可能并不適用于自身的項目需求,本文中實現(xiàn)的附件上傳區(qū)域支持超多類型附件分類型上傳,并且可根據(jù)特定條件具體展示某些類型的附件上傳,本文中是直接摘自具體的頁面,后面會抽時間單獨封裝出來一個附件上傳的組件。
一、Vue頁面內(nèi)附件展示區(qū)域代碼
<div class="retuinfo">
<div class="theadInfo-headline">
<span></span>
{{FileDivName}}
</div>
<Collapse v-model="defaultCollapse">
<Panel v-for="(item,pngIndex) in pngFileArray" v-bind:key="pngIndex" :name="item.num" v-show="item.isshow">
{{item.name}}
<div class="obsfilesdiv" slot="content">
<div v-for="(obs,index) in item.files" v-bind:key="index" class="obsfileslist">
<input ref="fileImg" type="file" accept="image/*;capture=camera" style="display: none;"
@change="setObsFile(item.num,1,obs.FileType,obs.Num,obs.Code)">
<label style="color:#6d7180; font-size: 20px;">{{obs.FileType}}<span style="color:red;"
v-show="obs.FileType!='其他'">*</span></label>
<ul class="obsfilesul">
<li v-for="(objitem,objindex) in obs.FileObj" v-bind:key="objindex">
<img :src="objitem.imgurl ? objitem.imgurl : fileUrl"
@click="showObsFiles(obs.FileFlag,objitem.imgurl)" />
<img src="../../../img/other/wrong.png" v-show="objitem.IsCanEdit" class="wrong_class"
@click="deleteObsFlie(item.num,index,objindex,objitem.imgid,objitem.imgurl)" />
</li>
<li style="border: 4px solid #f3f3f3;" @click="PlusClick(obs.FileType,obs.FileFlag,obs.Num)">
<img src="../../../img/icon-adds.png" alt="" />
</li>
<div style="clear:both;"></div>
</ul>
</div>
</div>
</Panel>
</Collapse>
</div>
<div class="modal" v-show="viewBigImg">
<div class="img-view-modal" style="text-align: right;">
<img :src="viewImgURL" style="width: 100%;" @click="hideShow(0)">
<Icon type="md-close" style="margin-right: 20px;" size='20' @click="hideShow(0)" />
</div>
</div>
</div>
Vue項目引入了以下UI框架:(若想拿來即用 需要先在main.js中引入)IView、MintUI、Vant 此段代碼只要確保引入IView即可正常使用
二、數(shù)據(jù)綁定設(shè)計
具體的不詳細展開說,數(shù)組與通過屬性控制,很好理解。
pngFileArray: [{
num: '0',
name: '整車',
isshow: localStorage.getItem("RoleName").indexOf('銘牌質(zhì)檢員') != -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('客戶經(jīng)理') != -1 ? true : false,
files: [{
FileType: '里程表照片',
Code: '701',
Num: 3,
FileFlag: 1,
FileObj: [],
IsNoFile: true
}
]
}
],
三、綁定的方法
1.圖片加載方法:
//獲取圖片列表
getImageList() {
this.$indicator.open({
text: '圖片加載中...',
spinnerType: 'snake'
});
let _this = this;
let downRequest ={
'crm_vin': this.parms.crm_vin,
'crm_vehiclenumber': this.parms.crm_vehiclenumber
};
let imgListParams = {
"ImageDownRequest": JSON.stringify(downRequest),
"username": localStorage.getItem("usernameone"),
"password": localStorage.getItem("password")
};
console.log("獲取圖片列表參數(shù):", imgListParams);
_this.$ajax.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;'; //配置請求頭
this.$ajax.post(this.imageListUrl, this.$qs.stringify(imgListParams)).then(resdata => {
_this.$indicator.close();
console.log("獲取到的圖片列表數(shù)據(jù):", resdata);
let data = resdata.data;
console.log("轉(zhuǎn)換后的圖片列表數(shù)據(jù):", data);
if (resdata.status != 200) {
_this.$toast({
message: '獲取圖片列表失??!',
duration: 3000
});
return;
}
//先清空原有的圖片列表
_this.pngFileArray.forEach((rr,index,array) =>{
for(var file=0;file<rr.files.length;file++){
_this.pngFileArray[index].files[file].FileObj = [];
_this.pngFileArray[index].files[file].IsNoFile = true;
}
});
//將圖片列表寫入頁面各圖片分類區(qū)域
for(var i=0;i<data.length;i++){
_this.pngFileArray.forEach((rr,index,array) =>{
for(var file=0;file<rr.files.length;file++){
if(data[i].crm_imagetypeno==rr.files[file].Code){
let putparm = {
"IsCanEdit":false,
"imgid": data[i].crm_careimageId,
"imgurl": data[i].ImageUrl
};
_this.pngFileArray[index].files[file].FileObj.push(putparm);
_this.pngFileArray[index].files[file].IsNoFile = false;
}
}
});
}
}).catch(function(error) {
_this.$indicator.close();
_this.$toast({
message: error,
duration: 3000
});
});
},
2.圖片展示方法
showObsFiles(type, url) { //展示圖片或視頻
console.log("展示附件:" + type);
if (type == 1) { //圖片
this.viewBigImg = true;
this.viewImgURL = url;
} else { //文件
this.$messagebox.alert("不支持查看文件,請到PC端操作!", "提示");
return;
}
},
3.上傳圖片相關(guān)方法
(最開始設(shè)計的是支持圖片、視頻和其他類型文件等上傳,項目中已實現(xiàn),本文中不做拓展)
PlusClick(type, flag, num) {
console.log("當前附件類型:" + type);
console.log("當前附件序號:" + num);
this.currentFileType = type;
if (flag == 1) { // 圖片上傳
this.$refs.fileImg[num].dispatchEvent(new MouseEvent('click'));
} else if (flag == 2) { // 視頻上傳
this.$refs.fileVideo[num].dispatchEvent(new MouseEvent('click'));
} else { // 其他類型文件
this.$refs.filElem[num].dispatchEvent(new MouseEvent('click'));
}
},
setObsFile(classify, type, obsFileType, num, code) { //保存圖片到crm中
var _this = this;
var inputFile; //文件流
console.log("圖片大分類:" + classify + " " + obsFileType + " " + num) + " 圖片編碼:" + code;
if (type == 1) {
inputFile = this.$refs.fileImg[num].files[0];
this.$refs.fileImg[num].value = '';
}
var fileName = inputFile.name;
if (!inputFile) {
return;
}
if (inputFile.type == 'image/jpg' || inputFile.type == 'image/jpeg' || inputFile.type == 'image/png' ||
inputFile.type ==
'image/gif') {} else {
this.$messagebox.alert("請上傳圖片", "提示");
return;
}
_this.$indicator.open({
text: '文件上傳中,請稍候...',
spinnerType: 'snake'
});
//圖片壓縮與轉(zhuǎn)換成base64文件流
var reader = new FileReader();
reader.readAsDataURL(inputFile);
reader.onloadend = function(e) {
let result = this.result;
console.log('********未壓縮前的圖片大小******** :' + result.length / 1024)
_this.pulic.dealImage(result, {}, function(base64) {
console.log('********壓縮后的圖片大小******** :' + base64.length / 1024)
_this.putObsFile(classify, fileName, base64, obsFileType, code);
});
//reader.result.substring(this.result.indexOf(',')+1);
// 'data:image/png;base64,'+reader.result
}
},
putObsFile(classify, fileName, base64, obsFileType, code) { //抽出公共上傳圖片文件方法
var _this = this;
let usernameone = this.$Base64.encode("administrator");
let password = this.$Base64.encode("pass@word1");
let parmsImages = {
crm_newenergyid: localStorage.getItem("crm_newenergyid"),
vin: _this.parms.crm_vin,
crm_vehiclenumber: _this.parms.crm_vehiclenumber,
CareType: code,
CreateBy: localStorage.getItem("SystemUserId"),
ImageStr: base64.split(",")[1],
username: usernameone,
password: password
}
let parms = {
ImageMessage: JSON.stringify(parmsImages)
}
console.log(JSON.stringify(parmsImages));
console.log(JSON.stringify(parms));
_this.$ajax.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;'; //配置請求頭
_this.$ajax.post(_this.imageSaveUrl, _this.$qs.stringify(parms))
.then(resdata => {
_this.$indicator.close();
console.log("接口響應數(shù)據(jù):", resdata);
let data = resdata.data;
console.log("轉(zhuǎn)換后的響應數(shù)據(jù):", data);
if (resdata.status != 200) {
_this.$toast({
message: '保存失??!接口調(diào)用異常',
duration: 3000
});
return;
}
//將上傳成功后的圖片url回寫到頁面的圖片分類url中
console.log("當前分類下的所有圖片類型:" + JSON.stringify(_this.pngFileArray[parseInt(classify)].files));
for (var i = 0; i < _this.pngFileArray[parseInt(classify)].files.length; i++) { //遍歷當前分類下的圖片類型數(shù)組 并賦值后臺返回的數(shù)據(jù)
if (obsFileType == _this.pngFileArray[parseInt(classify)].files[i].FileType) {
//設(shè)置圖片文件路徑等 putparm
let putparm = {
"IsCanEdit":true,
"imgid": data.crm_careimageId,
"imgurl": data.ImageUrl
};
_this.pngFileArray[parseInt(classify)].files[i].FileObj.push(putparm);
_this.pngFileArray[parseInt(classify)].files[i].IsNoFile = false;
}
}
_this.$messagebox.alert("附件上傳成功", "提示");
}).catch(err => {
console.log(JSON.stringify(err));
_this.$toast({
message: '上傳失敗',
duration: 1500
});
_this.$indicator.close();
});
},
4.刪除圖片方法
(本文中是只有未提交的圖片可刪除,若已提交過的圖片即頁面初始加載獲取到的圖片不可以刪除)
deleteObsFlie(classify,num,index,id,url) { //刪除附件
var _this = this;
this.$messagebox.confirm('確定刪除該圖片嗎?', "確認").then(action => {
var del_param = {
"id": id,
"url": url
};
_this.$indicator.open({
text: '刪除圖片中,請稍候...',
spinnerType: 'snake'
});
_this.$ajax.defaults.headers['Content-Type'] = 'application/x-www-form-urlencoded;'; //配置請求頭
_this.PromiseCall(_this.DelImgFilesURL, _this.$qs.stringify(del_param))
.then(data => {
_this.$indicator.close();
console.log(JSON.stringify(data));
if (data.status != 200) {
_this.$messagebox.alert("刪除圖片失敗", "提示");
return;
}
_this.pngFileArray[parseInt(classify)].files[num].FileObj.splice(index, 1);
_this.$toast({
message: '刪除圖片成功',
duration: 1500
});
}).catch(err => {
_this.doCatch(err);
_this.$toast({
message: '刪除圖片失敗'+err,
duration: 1500
});
_this.$indicator.close();
});
});
},
四、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;
}
最后附上實際效果圖:



到此這篇關(guān)于Vue頁面內(nèi)公共的多類型附件圖片上傳區(qū)域并適用折疊面板的文章就介紹到這了,更多相關(guān)Vue多類型附件圖片上傳內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue之使用echarts圖表setOption多次很卡問題及解決
這篇文章主要介紹了vue之使用echarts圖表setOption多次很卡問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-07-07
vue中{{}},v-text和v-html區(qū)別與應用詳解
這篇文章主要介紹了vue中{{}},v-text和v-html區(qū)別與應用詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-09-09
VUE2響應式原理使用Object.defineProperty缺點
這篇文章主要為大家介紹了VUE2響應式原理使用Object.defineProperty缺點示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-08-08

