美文网首页
vue + axios 上传图片到七牛组件

vue + axios 上传图片到七牛组件

作者: 索哥来了 | 来源:发表于2019-11-12 15:45 被阅读0次

关联文章,axios的封装:https://www.jianshu.com/p/f3268f923465
里面代码没有整理,可以直接抠出自己需要的部分


<template>
<div>
    <div class="c" v-if="onlyShow" :class="{imgParPr: (canHover && !hoverInBox)}">
        <div class="uploadImg_common_100_100" :class="{sizeNotFixed:sizeNotFixed}" v-for="(val,ind) in myImgArr" :key="ind">
            <img :src="val" @mouseenter="showPic(val,$event)" @mouseleave="hidePic">

            <em class="sw1" v-if="ind == 0 && !!showWords && showWords.type==1"><em>{{showWords.msg}}</em></em>
        </div>
    </div>

    <div class="c" v-else :class="{disabledPar:disabled, imgParPr: (canHover && !hoverInBox)}">
        <draggable v-model="myImgArr" :animation="500" @change="sortChange">
        <div class="uploadImg_common_100_100" :class="{sizeNotFixed:sizeNotFixed}" v-for="(val,ind) in myImgArr" :key="ind">
            <input class="file" type="file" accept="image/png,image/jpeg,image/gif" @change="update($event,1,ind)" @mouseenter="showPic(val,$event)" @mouseleave="hidePic"/>

            <img :src="val">

            <em class="sw1" v-if="ind == 0 && !!showWords && showWords.type==1"><em>{{showWords.msg}}</em></em>

            <i class="el-icon-circle-close remove" @click.prevent="remove(ind)"></i>
        </div>
        </draggable>
        <div class="uploadImg_common_100_100" v-if="!(limitLen && limitLen>0) || (limitLen && limitLen>0 && myImgArr.length < limitLen)">
            <input class="file" type="file" accept="image/png,image/jpeg,image/gif" multiple="multiple" @change="update($event,2)"/>
            <i class="el-icon-plus add"></i>
        </div>
    </div>
    <p class="uploadImg_tips" v-if="tips">{{tips}}</p>
</div>

<!-- Ex -->
<!-- <upload-multiimg
    :imgArr.sync = "formData.detail_arr"
    tips = "图片尺寸比例建议750*750px"
    :valid="{w:1,h:1}"
    :limitLen = "5"
></upload-multiimg> -->

</template>

<script>
import draggable from 'vuedraggable'
import myfetch from '@/function/fetch'

export default{
    data(){
        return {
            qiniuhost : this.$globalConfig.qiniuhost + '/',
            upUrl : this.$globalConfig.qiniu_upUrl,
            upToken : null,

            pl_picArr_once : [],//批量上传图片,用来暂时保存顺序

            myImgArr : [],
        }
    },
    props:{
        imgArr : Array,
        tips : String,

        valid : Object,//{w:1,h:1} 比例校验,不传则不校验
        // 也可拓展其他校验,比如大小校验,后续有需要再加

        disabled : {
            type : Boolean,
            default : false
        },
        sizeNotFixed: {
            type : Boolean,
            default : false
        },

        limitLen : Number,//选填,传了则大于这个值的时候 不再显示加号

        canHover: {//鼠标移上去显示大图
            type: Boolean,
            default: false
        },
        hoverInBox: {//配合canHover使用,true表示是在弹框里面,false表示直接在页面上
            type: Boolean,
            default: true
        },
        onlyShow: {//仅仅只是展示,不能编辑,页面效果还是和之前一样,去掉删除和新增
            type: Boolean,
            default: false
        },
        showWords: Object,//根据type来定,目前已定:type=1 取msg字段放在第一张图的顶部
    },
    components: {
        draggable
    },
    created(){
        this.myImgArr = [].concat(this.imgArr);
    },
    watch: {
        imgArr(val) {
            this.myImgArr = [].concat(val);//监听外部对props属性的变更,避免弹框使用v-show的时候  组件后面不会再赋值
        },
    },
    methods:{
        showPic(val,e){
            if(this.canHover){
                this.$commonFun.imgMouseleave();
                this.$commonFun.imgMouseenter(val, e, this.hoverInBox);
            }
        },
        hidePic(val,e){
            if(this.canHover){
                this.$commonFun.imgMouseleave();
            }
        },
        getToken(){
            this.$ajax.get('/common/uptoken',{}).then(res=>{
                this.upToken = res;
            })
        },
        uploading(param,config,pathName,cb){
            //使用axios
            /*this.$ajax.post(this.upUrl,param,config)
                .then(response=>{
                    cb(response)
                })*/

            //使用fetch
            myfetch(this.upUrl, param, 'post')
            .then(res => {
                cb(res)
            })
        },
        update(e,upLoadType,ind){

            /*
            e : event
            upLoadType : 1-单张替换上传 2-多张上传(+号上传)
            ind : 数字,数组里面第几个修改,单张替换需要
            */

            let me = this;
            let file;

            me.pl_picArr_once = [];// 清空

            let bl_count = 0;//记录比例不正确的值
            let has_upload = 0;//已经上传的

            if(upLoadType != 2){
                file = e.target.files[0];

                if(file){
                    thisUpFun(file);
                }
            }else{
                let file_arr = e.target.files;
                if(file_arr && file_arr.length>0){
                    for(let i =0;i<file_arr.length;i++){
                        if(i<file_arr.length){
                            thisUpFun(file_arr[i],file_arr.length,(i+1));
                        }
                    }
                }
            }

            function thisUpFun(file,totalInd,thisInd){
                let param = new FormData(); //创建form对象
                
                param.append('file',file,file.name)
                // console.log(param.get('file')); //FormData私有类对象,访问不到,可以通过get判断值是否传进去
                let config = {
                    headers:{'Content-Type':'multipart/form-data'}
                };
                if(me.upToken){
                    param.append('token',me.upToken);
                    me.uploading(param,config,file.name,function(res){
                        
                        callBack(res,totalInd,thisInd);
                    });
                }else{
                    me.$ajax.get('/common/uptoken',{}).then(res=>{
                        me.upToken = res;
                        param.append('token',me.upToken);
                        me.uploading(param,config,file.name,function(res){
                            
                            callBack(res,totalInd,thisInd);
                        });
                    })
                }
            }

            e.target.setAttribute('type','text');
            e.target.setAttribute('type','file');
            

            function callBack(res,totalInd,thisInd){

                let newArr = [].concat(me.myImgArr);

                if(upLoadType != 2){
                    // 单张替换上传

                    if(me.valid && me.$commonFun.testInt(me.valid.w) && me.$commonFun.testInt(me.valid.h)){

                        let w = Number(me.valid.w),
                            h = Number(me.valid.h);

                        if(me.$commonFun.multi(res.h , w) != me.$commonFun.multi(res.w , h)){
                            me.$message('图片尺寸比例必须'+w+':'+h+'!');
                            return false;
                        }
                        newArr[ind] = me.qiniuhost +res.key;    
                    }else{
                        newArr[ind] = me.qiniuhost +res.key;
                    }

                    me.myImgArr = [].concat(newArr);
                }else{
                    has_upload += 1;

                    if(me.valid && me.$commonFun.testInt(me.valid.w) && me.$commonFun.testInt(me.valid.h)){

                        let w = Number(me.valid.w),
                            h = Number(me.valid.h);

                        if(me.$commonFun.multi(res.h , w) != me.$commonFun.multi(res.w , h)){

                            bl_count += 1;
                        }else{
                            me.pl_picArr_once.push({
                                ind : Number(thisInd),
                                src : me.qiniuhost +res.key
                            })
                        }
                    }else{
                        me.pl_picArr_once.push({
                            ind : Number(thisInd),
                            src : me.qiniuhost +res.key
                        })
                    }

                    if(totalInd && has_upload == totalInd){

                        let arr = [].concat(me.pl_picArr_once);
                        me.pl_picArr_once = [];

                        arr.sort((a,b)=>{
                            return a.ind - b.ind;
                        });


                        let arr_src = [];
                        arr.forEach(function(v,i){
                            arr_src.push(v.src)
                        })

                        me.myImgArr = me.myImgArr.concat(arr_src);

                        if(bl_count>0){
                            me.$message('所选图片中,有'+(totalInd-bl_count)+'张上传成功,'+bl_count+'张上传失败,尺寸比例应为'+me.valid.w+':'+me.valid.h+'!');
                            return false;
                        }
                    }
                }

                me.$emit('update:imgArr',me.myImgArr);
            }
        },
        remove(ind){
            this.myImgArr.splice(ind, 1);
            this.$emit('update:imgArr',this.myImgArr);
        },
        sortChange(){
            // console.log(this.myImgArr)
            this.$emit('update:imgArr',this.myImgArr);
        }
    }
}
</script>

<style lang="scss" scoped>
.uploadImg_common_100_100{
    width: 98px;
    height: 98px;
    border: 1px dashed #d9d9d9;
    cursor: pointer;
    position: relative;
    float: left;
    margin-bottom: 10px;
    margin-right: 10px;
    background: #eee;
    .file {
        width: 100%;
        height: 100%;
        position: absolute;
        left: 0;
        top: 0;
        opacity: 0;
        cursor: pointer;
        z-index: 9;
    }
    .add {
        font-size: 28px;
        color: #8c939d;
        width: 100%;
        height: 100%;
        line-height: 98px;
        text-align: center;
    }
    img {
        width: 98px;
        max-height: 98px;
    }
    .remove {
        position: absolute;
        right: -8px;
        top: -8px;
        font-size: 16px;
        z-index: 10;
        background:#fff;
        border-radius: 50%;
    }
    .sw1{
        position: absolute;
        left: 0;
        top: 0;
        width: 100%;
        height: 20px;
        line-height: 20px;
        text-align: center;
        background: rgba(0,0,0,.5);
        color: #fff;
        font-size: 12px;
    }
}
.uploadImg_common_100_100.sizeNotFixed{
    img {
        width: auto;
        height: auto;
        max-width: 98px;
        max-height: 98px;
    }
}

.disabledPar{
    .uploadImg_common_100_100{
        cursor: not-allowed !important;
        opacity: .8!important;
        input[type="file"]{
            display: none;
        }
    }
}

.margin_none{
    .uploadImg_common_100_100{
        margin-right: 0;
        margin-bottom: 0;
    }
}

.imgParPr{
    padding-right: 400px;
}

.mainPic_par{
    .uploadImg_common_100_100:first-child{
        &:before{
            content: 'SKU主图';
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 20px;
            line-height: 20px;
            text-align: center;
            background: rgba(0,0,0,.5);
            font-size: 12px;
            color: #fff;
        }
    }
}
</style>

相关文章

网友评论

      本文标题:vue + axios 上传图片到七牛组件

      本文链接:https://www.haomeiwen.com/subject/oslqictx.html