在vue中使用plupload上傳圖片到七牛(著重解決moxie is not defined問題)
阿新 • • 發佈:2019-02-05
在傳統的jquery或者原生JS環境下結合plupload上傳到七牛的案例就不說了,一搜一大片,這裡重點說說使用了vue之後,在vue環境下要保持相同的體驗度上傳圖片到七牛,下面就是搞了接近兩天摸索出來的,過程只想MMP,但是還是得到了滿意的結果,算是功夫不負苦心人啊(這個過程真的是坑太多了)!
這個排坑的過程就多說了,搞來搞去就是plupload和qiniu的js版本對不上的問題,然後就是各種變數找不到的問題,一部分是參考github上的解決辦法解決的,一部分自己除錯程式碼解決,經歷不可說不痛苦,唉!
著重說幾點要注意的地方:
1.相對JS的引入,這裡沒有使用壓縮之後的,直接使用的原始碼,因為要除錯啊,不過有了webpack,也可以直接使用原始碼,因為最終是要打包的,無所謂引用什麼,但建議還是引用原始碼,用了你就知道了:
//這裡使用相對路徑,就是該檔案相對於static目錄的路徑
window.mOxie = window.moxie = require('../../../static/js/plupload/moxie')
require('../../../static/js/plupload/plupload.dev')
require('../../../static/js/qiniu/qiniu')
2.對應的plupload.dev.js:
注意看版本號:2.3.6,修改原始碼部分(括號裡面的this改成window):
exports.plupload = plupload; }(window, moxie)); }));
3.對應的qiniu.js,用的是目前的最新版,等下看js原始檔就知道了,在原始碼裡面要加下面這句程式碼:
mOxie.Env = mOxie.core.utils.Env;
4.最最坑的moxie.js,尼瑪就是這個js搞了半天,在這個原始碼的最後面加上:
window.mOxie = exports.mOxie;
其他的就是使用部分了,還是貼一下,不然文章太短了,哈哈:
vue元件部分
<template> <!-- 圖片上傳元件 --> <div class="sg-upload-area" :id="uploadContainerId"> <img :src="defaultImg" alt="" class="sg-upload-img" :id="uploadImgId" :style="imgButtonStype"> <span class="sg-img-loading" v-if="ifShowLoading"></span> <span class="sg-img-progress-bar" v-show="ifShowBar">{{progress_percent}}</span> </div> </template> <script> //這裡使用相對路徑,就是該檔案相對於static目錄的路徑 window.mOxie = window.moxie = require('../../../static/js/plupload/moxie') require('../../../static/js/plupload/plupload.dev') require('../../../static/js/qiniu/qiniu') export default { props:['imgButtonStype'], data() { return { defaultImg:'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1536823040797&di=656672375293c1e3f8c0719d90bdb2b2&imgtype=0&src=http%3A%2F%2Fwww.qqzhi.com%2Fuploadpic%2F2015-01-08%2F143039142.jpg', ifShowLoading:0, ifShowBar:0,//進度條顯示隱藏 progress_percent:"0%", img_cuid:new Date().getTime(),//圖片唯一ID upload_area:0, upload_img:0, qiniu_domain:"https://img.senguo.cc/",//自己去修改,圖床域名 qiniu_token:"Pm0tzHLClI6iHqxdkCbwlSwHWZycbQoRFQwdqEI_:BmvYWOi-8S4u4ed7NEfiQ2YXS5E=:eyJkZWFkbGluZSI6MTUzNzM1MTEzMCwic2NvcGUiOiJzaG9waW1nIn0=" }; }, mounted() { this.initUpload() }, methods:{ initUpload() { let _vue = this; let uploader = Qiniu.uploader({ runtimes: 'html5,flash,html4', browse_button: _vue.upload_img, container: _vue.upload_area, max_file_size: '10mb', filters : { // max_file_size : '4mb',//限制圖片大小 mime_types: [ {title : "image type", extensions : "jpg,jpeg,png"} ] }, flash_swf_url: '../../../static/js/plupload/Moxie.swf', dragdrop: false, chunk_size: '4mb', domain: _vue.qiniu_domain, uptoken: _vue.qiniu_token, unique_names: false, save_key: false, auto_start: true, resize: {width: 800}, init: { 'BeforeUpload':function(up, file){ }, 'FilesAdded': function (up, files) { var file = files[0]; !function(){ _vue.previewImage(file,function(imgsrc){ _vue.defaultImg = imgsrc; }); }(); _vue.ifShowBar = 1; }, 'UploadProgress': function (up, file) { console.log(file.percent) _vue.progress_percent = file.percent+"%" }, 'FileUploaded': function (up, file, info) { //$("#"+file.id).attr({"url":qiniu_domain+file.id+".jpg","src":qiniu_domain+file.id+".jpg"+"?imageView2/1/w/100/h/100"}); _vue.defaultImg = _vue.qiniu_domain+file.id+".jpg"; }, 'Error': function (up, err, errTip) { if (err.code == -600) { alert("上傳圖片大小請不要超過4M"); } else if (err.code == -601) { alert("上傳圖片格式只能為png、jpg圖片"); } else if (err.code == -200) { alert("當前頁面過期,請重新整理頁面後再上傳"); } else { alert(err.code + ": " + err.message); } up.removeFile(err.file.id); }, 'Key': function (up, file) { var key = file.id+".jpg"; return key; } } }); }, /*轉化圖片為base64預覽*/ previewImage(file,callback) {//file為plupload事件監聽函式引數中的file物件,callback為預覽圖片準備完成的回撥函式 if(!file || !/image\//.test(file.type)) return; //確保檔案是圖片 if(file.type=='image/gif'){//gif使用FileReader進行預覽,因為mOxie.Image只支援jpg和png let fr = new moxie.image.Image(); fr.onload = function(){ callback(fr.result); fr.destroy(); fr = null; }; fr.readAsDataURL(file.getSource()); }else{ let preloader = new moxie.image.Image(); preloader.onload = function() { preloader.downsize(100,100,true);//先壓縮一下要預覽的圖片,寬,高 let imgsrc = preloader.type=='image/jpeg' ? preloader.getAsDataURL('image/jpeg',70) : preloader.getAsDataURL(); //得到圖片src,實質為一個base64編碼的資料 callback && callback(imgsrc); //callback傳入的引數為預覽圖片的url preloader.destroy(); preloader = null; }; preloader.load( file.getSource() ); } } }, computed:{ uploadImgId() { this.upload_img = "upload_img_"+this.img_cuid return this.upload_img }, uploadContainerId() { this.upload_area = "upload_container_"+this.img_cuid return this.upload_area } } }; </script> <style lang="scss" scoped> .sg-upload-area{ display: inline-block; position: relative; cursor: pointer; .sg-upload-img{ display: inline-block; width: 60px; height: 60px; } .sg-img-loading{ position: absolute; width:100%; height: 100%; z-index: 10; } .sg-img-progress-bar{ position: absolute; left:0; bottom:0; width:100%; height: 14px; background-color: rgba(0, 0, 0, 0.6); color: #fff; font-size: 10px; line-height: 14px; text-align: center; z-index:10; } } </style>
元件的使用(非常簡單):
<template>
<div>
<upload-img imgButtonStype="width:100px;height:100px;"></upload-img>
</div>
</template>
<script>
import UploadImg from '@/components/common/UploadImg'
export default {
components: {UploadImg},
data() {
return {
}
},
methods: {
},
mounted() {
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="scss" scoped>
</style>
差不多就是這樣了,我把我的static裡面的檔案打包一份,再傳一下就ok了;