1. 程式人生 > >移動端使用vue單頁面圖片上傳

移動端使用vue單頁面圖片上傳

效果如下:


圖片驗證簽名驗證資訊 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>