移動端使用vue單頁面圖片上傳
阿新 • • 發佈:2019-02-04
效果如下:
圖片驗證簽名驗證資訊 url如下:圖片驗證資訊與後端同學進行對接,可通過介面或url傳遞到前端。
http://192.168.1.9:8083?limit=5&label=‘xxx’&OSSAccessKeyId=LTAIpX3MEAfuMYiq&policy=eyJleHBpcmF0aW9uIjoiMjAxOC0wNy0wNlQwOToyNToxNVoiLCJjb25kaXRpb25zIjpbWyJjb250ZW50LWxlbmd0aC1yYW5nZSIsMCwxMDQ4NTc2MDAwXSxbInN0YXJ0cy13aXRoIiwiJGtleSIsImltYWdlXC9wcmVzaWduZWRcL2NlcnRcLyJdXX0=&signature=UDWBhlwrYQrVt7rC3r5OXDcd/gs=&dir=image/presigned/cert/&host=http://xxxxxx.com&_t=1530840135305
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <title>上傳圖片</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width,initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="apple-mobile-web-app-status-bar-style" content="black" /> <meta content="telephone=no,email=no" name=format-detection /> <meta name="renderer" content="webkit" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="renderer" content="webkit|ie-comp|ie-stand" /> <!--<script src="/js/vue.min.js"></script> <script src="/js/jquery.min.js"></script> <script src="/js/plupload-3.1.2/plupload.full.min.js"></script>--> <!-- cdn --> <script src="http://vuejs.org/js/vue.min.js"></script> <script src="http://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script> <script src="http://cdn.bootcss.com/plupload/3.1.2/plupload.full.min.js"></script> <style> /* 去除瀏覽器預設樣式reset */ html, body, body div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, figure, footer, header, menu, nav, section, time, mark, audio, video, details, summary { margin: 0; padding: 0; border: 0; font-size: 100%; font-weight: normal; vertical-align: baseline; background: transparent; -webkit-tap-highlight-color:rgba(255,255,255,0); } html, body { width: 100%; height: 100%; font-size: 0.28rem; } main, article, aside, figure, footer, header, nav, section, details, summary {display: block;} ul {list-style: none;} table {border-collapse: separate; border-spacing: 0;} th {font-weight: bold; vertical-align: bottom;} td {font-weight: normal; vertical-align: top;} input{ outline: none; border: none; } /* 頁面樣式 */ .cf { zoom: 1; } .cf:after { content: ""; display: table; clear: both; } .fl{ float: left; } #app{ width: 100%; height: 100%; } .logo{ height: 2rem; display: flex; align-items: center; justify-content: center; } .logoImg{ width: 1.6rem; height: 1.6rem; } .imgContent{ margin-top: 0.2rem; } .imgContent p{ font-size:0.26rem; color: #000000; text-align: center; } .imgBody{ margin-top: 0.4rem; } .imgCenter{ margin: 0 auto; width: 6.6rem; } .pic-item { position:relative; width: 1.8rem; height: 1.8rem; margin:0 .4rem .4rem 0; } .pic-item img { width: 100%; height: 100%; } .delete-pic{ position:absolute; top:-.15rem; right:-.15rem; border: 1px solid red; border-radius: 50%; z-index:1; width:.38rem; height:.38rem; text-align: center; line-height:.38rem; } .icon{ font-size:.12rem; color:red; display:inline-block; } .onloadContent{ width: 100%; height: 2rem; text-align: center; line-height: 2rem; bottom: 0; left: 0; } .selectFile{ width: 1.6rem; height: 1.6rem; line-height: 1.6rem; text-align: center; display: inline-block; background-color: #c6ae6c; border-radius: 50%; color: #ffffff; margin-right: 0.2rem; } .selectFile p{ display: inline-block; width: 0.6rem; font-size: 0.24rem; line-height: 0.4rem; vertical-align: middle; } .confirmLoad{ width: 1.6rem; height: 1.6rem; line-height: 1.6rem; text-align: center; display: inline-block; background-color: black; border-radius: 50%; color: #ffffff; } .confirmLoad p{ display: inline-block; width: 0.6rem; font-size: 0.24rem; line-height: 0.4rem; vertical-align: middle; } /* 蒙版 */ .appMask{ width: 100%; height: 100%; z-index: 10; top: 0; position: fixed; background-color: rgba(0, 0, 0, 0.3) } /* 圖片彈出框 */ .imgPop{ width: 6rem; height: 8rem; background-color: red; position: fixed; z-index: 20; top: 12%; left: 50%; transform: translateX(-50%); } .popImg{ width: 100%; height: 100%; } .popClose{ position:absolute; top:-.15rem; right:-.15rem; border: 1px solid red; border-radius: 50%; z-index:21; width:.38rem; height:.38rem; text-align: center; line-height:.38rem; } </style> </head> <body> <div id="app"> <div class="logo"> <img class="logoImg" src="" alt=""> </div> <div class="imgContent"> <p>請選擇{{label}}或拍照上傳</p> <p>最多不超過{{limit}}張圖片</p> <div class="imgBody"> <div class="imgCenter cf"> <div class="pic-item fl" v-for="(imgsrc,index) in images" :key="index" @click="showPop(imgsrc)"> <img :src="imgsrc" alt=""> <span class="delete-pic" @click.stop="removeSelectImage(index)"> <i class="icon">X</i> </span> </div> </div> </div> </div> <div class="onloadContent"> <input type="button" id="selectBtn" class='btn selectFile' value="選擇上傳" /> <input type="button" @click="uplaod" class='btn confirmLoad' value="確認上傳" /> </div> <!-- 蒙版 --> <div class="appMask" v-show="popStatus"></div> <!-- 彈出層 --> <div class="imgPop" v-show="popStatus"> <img class="popImg" :src=currentImg alt=""> <span class="popClose" @click="closePop"> <i class="icon">X</i> </span> </div> </div> <script> // 引入rem,使用rem單位,對不同手機螢幕進行適配 (function (doc, win) { var docEl = doc.documentElement var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize' var recalc = function () { var clientWidth = docEl.clientWidth if (!clientWidth) return if (clientWidth >= 750) { docEl.style.fontSize = '100px' // 1rem = 100px } else { docEl.style.fontSize = 100 * (clientWidth / 750) + 'px' } } if (!doc.addEventListener) return win.addEventListener(resizeEvt, recalc, false) doc.addEventListener('DOMContentLoaded', recalc, false) })(document, window) // 擷取url指定引數 function getUrlParam(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //構造一個含有目標引數的正則表示式物件 var r = window.location.search.substr(1).match(reg); //匹配目標引數 if (r != null) return decodeURIComponent(r[2]); return null; //返回引數值 } var vapp = new Vue({ el : '#app', data : { ossSignature : {OSSAccessKeyId:"",policy:"",signature:"",dir:'',host:'',success_action_status:'0',key:""}, limit : 1, label : '', images:[], postImages:[], uploader : null, popStatus: false, //是否顯示蒙版和圖片彈出框 currentImg:'' // 點開大圖的當前圖片 }, created : function(){ console.log('created'); this.ossSignature.OSSAccessKeyId = getUrlParam('OSSAccessKeyId'); this.ossSignature.policy = getUrlParam('policy'); this.ossSignature.signature = getUrlParam('signature'); this.ossSignature.host = getUrlParam('host'); this.ossSignature.dir = getUrlParam('dir'); this.ossSignature.success_action_status = '200'; this.ossSignature.key = ''; this.limit = getUrlParam('limit'); this.existed = getUrlParam('existed'); this.label = getUrlParam('label'); document.title = this.label; }, mounted: function(){ var self = this; this.uploader = new plupload.Uploader({ runtimes : 'html5,gears,browserplus,silverlight,flash,html4', browse_button : 'selectBtn', container: document.getElementById('app'), url : this.ossSignature.host, //伺服器端的上傳頁面地址 flash_swf_url : 'lib/plupload-2.1.2/js/Moxie.swf', silverlight_xap_url : 'lib/plupload-2.1.2/js/Moxie.xap', filters: { mime_types : [ //只允許上傳圖片和zip,rar檔案 { title : "Image files", extensions : "jpg,png,bmp,jpeg" } ], max_file_size : '10mb', //最大隻能上傳10mb的檔案 prevent_duplicates : true //不允許選取重複檔案 }, init : { FilesAdded: function(up, files) { var oldLen = up.files.length - files.length; up.files.splice(self.limit, up.files.length); files = files.slice(0, self.limit - oldLen); files = files || []; plupload.each(files, function(file) { console.log(file); if (!file || !/image\//.test(file.type)) return; //確保檔案是圖片 var fr = new plupload.FileReader(); fr.onload = function () { file.imgsrc = fr.result; self.images.push(fr.result); //fr.destroy(); fr = null; } fr.readAsDataURL(file.getSource()); }); }, BeforeUpload:function(up, file){ var fileName = file.name; var suffix = fileName.split('.').pop(); fileName = self.random_string() + '.'+suffix; self.ossSignature.key = self.ossSignature.dir + fileName; file.remotePath = self.ossSignature.key; }, FileUploaded: function(up, file, info) { if (info.status == 200){ console.log(file.remotePath); } }, UploadComplete : function(uploader){ let len = uploader.files.length; for (var i=0;i<len;i++){ self.postImages.push(self.ossSignature.host+'/'+uploader.files[i].remotePath); } self.postImages.splice(self.limit,uploader.files.length) $.ajax({ type : 'post', url: '/upload/image/set', data : {signature:self.ossSignature.signature,images:self.postImages}, dataType: 'json', success: function (data) { alert('上傳成功'); } }); } } }); this.uploader.init(); }, methods : { selectImage: function(file, fileList){ for (var i=0;i<fileList.length;i++){ this.images.push(fileList[i].url); } }, removeSelectImage : function(index){ this.images.splice(index,1); console.log(JSON.stringify(this.uploader.files)); this.uploader.files.splice(index,1); console.log(JSON.stringify(this.uploader.files)); }, random_string : function(len){ len = len || 32; let chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; let maxPos = chars.length; let pwd = ''; for (let i = 0; i < len; i++) { pwd += chars.charAt(Math.floor(Math.random() * maxPos)); } return pwd; }, uplaod : function(){ if (this.images.length<=0){ alert('請選擇要上傳的照片'); return } this.uploader.setOption({ 'url': this.ossSignature.host, 'multipart_params': this.ossSignature }); this.uploader.start(); }, // 顯示蒙版和彈出框 showPop (imgsrc){ this.currentImg = imgsrc this.popStatus = true }, // 關閉蒙版和彈出框 closePop (){ this.popStatus = false } } }); </script> </body> </html>