1. 程式人生 > >在vue中使用plupload上傳圖片到七牛(著重解決moxie is not defined問題)

在vue中使用plupload上傳圖片到七牛(著重解決moxie is not defined問題)

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

下載地址