在傳統的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了;