结合axios(formdata)+vue-cropper+element ui实现头像图片剪切上传

4 篇文章 0 订阅
1 篇文章 0 订阅

萌新用vue + axios + formdata 上传文件的爬坑之路
https://blog.csdn.net/qq_41688165/article/details/80834842

结合vue-cropper与element ui实现头像图片剪切上传
https://www.jianshu.com/p/039cfd0dfd05

<template>
    <div class="certification-mask">
        <div class="certification-box">
            <div class="certification-top align-justify-items">修改用户头像</div>
            <div @click="$emit('certification-close')" class="certification-close">
                <img src="../assets/alert_close.png">
            </div>
            <div class="cropper-content clearfix">
                <div class="cropper-left">
                    <div class="cropper">
                        <vueCropper
                                ref="cropper"
                                :img="option.img"
                                :outputSize="option.size"
                                :outputType="option.outputType"
                                :info="true"
                                :full="option.full"
                                :canMove="option.canMove"
                                :canMoveBox="option.canMoveBox"
                                :original="option.original"
                                :autoCrop="option.autoCrop"
                                :autoCropWidth="option.autoCropWidth"
                                :autoCropHeight="option.autoCropHeight"
                                :fixedBox="option.fixedBox"
                                @realTime="realTime"
                                @imgLoad="imgLoad"
                        ></vueCropper>
                    </div>
                    <div class="cropper-operate">
                        <button class="el-button is-circle el-button--primary" @click="rotateRight">
                            <svg t="1580884496485" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1400" width="20" height="20"><path d="M138.72 335.55l4.84-2.8a19 19 0 0 1 26 6.94l23.16 40c57.86-151.64 214.17-254.64 390.84-230.62 163 22.17 291.67 154.12 310.25 317.61C918.81 686.65 747.44 873 532.54 873a362.58 362.58 0 0 1-265.35-115c-12-12.77-3.19-33.64 14.31-33.64a32 32 0 0 1 22.84 9.4c71.09 72.28 176.25 110.94 289.46 90C726 799.19 829.09 691.58 848.91 558.58 878.52 360 725.47 189.27 532.54 189.27c-136 0-252.08 84.86-298.43 204.48l39.18-22.67a21.82 21.82 0 0 1 21.86 37.78L212 456.95a21.82 21.82 0 0 1-29.82-8 22 22 0 0 1-1.06-2.1l-49.38-85.34a19 19 0 0 1 6.98-25.96z" p-id="1401" fill="#ffffff"></path></svg>
                        </button>
                        <button class="el-button is-circle el-button--success" @click="rotateLeft">
                            <svg t="1580884444251" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1166" width="20" height="20"><path d="M886.74 335.55l-4.84-2.8a19 19 0 0 0-26 6.94l-23.16 40C774.88 228.08 618.56 125.08 441.9 149.11c-163 22.17-291.67 154.12-310.25 317.61C106.65 686.65 278 873 492.92 873a362.58 362.58 0 0 0 265.34-115c12-12.77 3.19-33.64-14.31-33.64a32 32 0 0 0-22.84 9.4C650 806 544.86 844.69 431.65 823.7c-132.22-24.51-235.28-132.12-255.11-265.12C146.93 360 300 189.27 492.92 189.27c136 0 252.08 84.86 298.43 204.48l-39.18-22.67a21.82 21.82 0 0 0-21.86 37.78l83.1 48.09a21.82 21.82 0 0 0 29.82-8 22 22 0 0 0 1.06-2.1l49.38-85.34a19 19 0 0 0-6.93-25.96z" p-id="1167" fill="#ffffff"></path></svg>
                        </button>
                        <button style="padding: 10px;" class="el-button is-circle el-button--danger" @click="changeScale(1)">
                            <svg t="1580884167725" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2247" width="16" height="16"><path d="M863.328262 481.340895l-317.344013 0.099772L545.984249 162.816826c0-17.664722-14.336138-32.00086-32.00086-32.00086s-31.99914 14.336138-31.99914 32.00086l0 318.400215-322.368714-0.17718c-0.032684 0-0.063647 0-0.096331 0-17.632039 0-31.935493 14.239806-32.00086 31.904529-0.096331 17.664722 14.208843 32.031824 31.871845 32.095471l322.59234 0.17718 0 319.167424c0 17.695686 14.336138 32.00086 31.99914 32.00086s32.00086-14.303454 32.00086-32.00086L545.982529 545.440667l317.087703-0.099772c0.063647 0 0.096331 0 0.127295 0 17.632039 0 31.935493-14.239806 32.00086-31.904529S880.960301 481.404542 863.328262 481.340895z" p-id="2248" fill="#ffffff"></path></svg>
                        </button>
                        <button style="padding: 10px;" class="el-button is-circle el-button--warning" @click="changeScale(-1)">
                            <svg t="1580884468915" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2481" width="16" height="16"><path d="M863.74455 544.00086 163.424056 544.00086c-17.664722 0-32.00086-14.336138-32.00086-32.00086s14.336138-32.00086 32.00086-32.00086l700.320495 0c17.695686 0 31.99914 14.336138 31.99914 32.00086S881.440237 544.00086 863.74455 544.00086z" p-id="2482" fill="#ffffff"></path></svg>
                        </button>
                    </div>
                </div>
                <div class="cropper-right">
                    <!--展示区域-->
                    <div class="show-preview">
                        <div :style="previews.div" class="preview">
                            <img :src="previews.url" :style="previews.img"/>
                        </div>
                    </div>
                    <!--按钮区域-->
                    <el-upload
                            class="upload-demo"
                            ref="upload"
                            action="https://jsonplaceholder.typicode.com/posts/"
                            :before-upload="beforeUpload"
                            :on-preview="handlePreview"
                            :on-remove="handleRemove"
                            :auto-upload="true"
                            :show-file-list="false"
                    >
                        <button class="el-button el-button--primary" slot="trigger" size="small" type="primary">选取图片</button>
                        <button class="el-button el-button--success" style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传头像</button>
                        <!-- <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div> -->
                    </el-upload>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    import {VueCropper} from "vue-cropper";
    import axios from 'axios';
    export default {
        name: 'tailoringUpload',
        components: {
            VueCropper
        },
        created(){
        },
        methods: {
            submitUpload(file) {
                window.console.log(file);
                // this.$refs.upload.submit();
                this.finish("blob");
            },
            handleRemove(file, fileList) {
                window.console.log(file, fileList);
            },
            handlePreview(file) {
                window.console.log(file);
                //   let data = window.URL.createObjectURL(new Blob([file]));
                //   this.option.img = data;
            },
            beforeUpload(file) {
                window.console.log("上传文件");
                window.console.log(file);
                let data = window.URL.createObjectURL(new Blob([file]));
                this.fileName = file.name;
                this.option.img = data;
            },
            //放大/缩小
            changeScale(num) {
                window.console.log("changeScale");
                num = num || 1;
                this.$refs.cropper.changeScale(num);
            },
            //坐旋转
            rotateLeft() {
                window.console.log("rotateLeft");
                this.$refs.cropper.rotateLeft();
            },
            //右旋转
            rotateRight() {
                window.console.log("rotateRight");
                this.$refs.cropper.rotateRight();
            },
            //上传图片(点击上传按钮)
            finish(type) {
                let formData = new FormData();
                // 输出
                if (type === "blob") {
                    this.$refs.cropper.getCropBlob(data => {
                        let img = window.URL.createObjectURL(data);
                        this.model = true;
                        this.modelSrc = img;
                        formData.append("file", data, this.fileName);
                        this.http.post('file/upload-image', formData, {
                            headers: {'Access-Token': ''}
                        }).then(response => {
                            window.console.log("上传成功!", response);
                            if(response.status == 200){
                                var res = response.data;
                                if (res.status_code == 200) {
                                    this.upload_status = '上传成功!';
                                }else{
                                    this.upload_status = res.details.err_msg;
                                }
                            }else{
                                this.upload_status = '上传失败';
                            }
                        }).catch(function (error) {
                            window.console.log(error.response);
                            if (error.response) {
                                if(error.response.status == 401){
                                    //登录失效的时候,跳转到登录页面
                                    window.location.href="/dl?redirect="+window.location.pathname;
                                }else{
                                    // 请求已发出,但服务器响应的状态码不在 2xx 范围内
                                    this.upload_status = error.response.data;
                                }
                            } else {
                                window.console.log( "Error", error.message );
                                this.upload_status = error.message;
                            }
                        });
                    });
                } else {
                    this.$refs.cropper.getCropData(data => {
                        this.model = true;
                        this.modelSrc = data;
                    });
                }
            },
            // 实时预览函数
            realTime(data) {
                window.console.log("realTime");
                this.previews = data;
            },
            imgLoad(msg) {
                window.console.log("imgLoad");
                window.console.log(msg);
            }
        },
        data(){
            return {
                http: axios.create({
                    baseURL: 'https://xxx.upload.com/api/',  //生产环境
                    withCredentials: false, //是否开启跨域,开启后可以设置自定义的header头,但是后端要开启*以及允许哪些header头
                    headers: {
//                     'Content-Type':'multipart/form-data',  //上传文件的时候,不用设置,会自动设置成  multipart/form-data
//                    不能有拦截器,一旦添加拦截器,数据会自动变成Object,然后浏览器给出的是application/json,
                    },
                }),
                headImg: "",
                //剪切图片上传
                crap: false,
                previews: {},
                option: {
                    img: "",
                    outputSize: 1, //剪切后的图片质量(0.1-1)
                    full: false, //输出原图比例截图 props名full
                    outputType: "png",
                    canMove: true,
                    original: false,
                    canMoveBox: true,
                    autoCrop: true,
                    autoCropWidth: 150,
                    autoCropHeight: 150,
                    fixedBox: true
                },
                fileName: "", //本机文件地址
                downImg: "#",
                imgFile: "",
                uploadImgRelaPath: "" //上传后的图片的地址(不带服务器域名)
            }
        }
    }
</script>

<style scoped lang="less">
    .certification-mask {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        right: 0;
        background-color: rgba(85, 85, 85, 0.5);
        vertical-align: middle;
        z-index: 99999;
        display: inline-grid;
        display: flex;
        .certification-box {
            color: #222;
            border-radius: 5px;
            background-color: #fff;
            /*width: 800px;*/
            /*height: 480px;*/
            margin: auto;
            padding: 20px 50px;
            position: relative;
            .certification-top{
                font-weight: bold;
                height:45px;
                line-height: 45px;
                vertical-align: middle;
                color:#222;
                font-size: 16px;
                border-bottom: 1px solid #F2F2F2;
                text-align: center;
                margin-bottom: 30px;
            }
            .certification-close {
                width: 34px;
                height: 34px;
                position: absolute;
                top: 0;
                right: 0;
                cursor: pointer;
                img {
                    margin: 12px;
                    width: 10px;
                    height: 10px;
                }
            }

        }
    }

    .cropper-content {
        min-width: 540px;
        /*display: flex;*/
        /*border:1px solid blue;*/
        //   display: -webkit-flex;
        //   justify-content: flex-end;
        //   -webkit-justify-content: flex-end;
        .cropper-left{
            float: left;
            width: 260px;
            /*height:400px;*/
            /*border: 1px solid olivedrab;*/
            .cropper {
                width: 260px;
                height: 260px;
            }
            .cropper-operate{
                margin: 20px auto;
                button{
                    width:40px;
                    height:40px;
                    margin-right: 33px;
                    &:nth-of-type(4){
                        margin-right: 0;
                    }
                }
            }
        }
        .cropper-right{
            margin-left:20px;
            float: left;
            .show-preview {
                width: 150px;
                height:155px;
                overflow: hidden;
                flex: 1;
                -webkit-flex: 1;
                display: flex;
                display: -webkit-flex;
                justify-content: center;
                -webkit-justify-content: center;
                margin: auto;
                .preview {
                    overflow: hidden;
                    border-radius: 50%;
                    border: 1px solid #cccccc;
                    background: #cccccc;
                    width:150px !important;
                    height:150px !important;
                }
            }
            .upload-demo{
                margin:20px auto;
                button{
                    height:40px;
                    padding:auto 5px;
                }
            }
        }
    }

    .el-button {
        display: inline-block;
        line-height: 1;
        white-space: nowrap;
        cursor: pointer;
        background: #FFF;
        border: 1px solid #DCDFE6;
        color: #606266;
        -webkit-appearance: none;
        text-align: center;
        -webkit-box-sizing: border-box;
        box-sizing: border-box;
        outline: 0;
        margin: 0;
        -webkit-transition: .1s;
        transition: .1s;
        font-weight: 500;
        -moz-user-select: none;
        -webkit-user-select: none;
        -ms-user-select: none;
        padding: 12px 20px;
        font-size: 14px;
        border-radius: 4px;
    }
    .el-button.is-circle {
        border-radius: 50%;
        padding: 9px;
    }
    .el-button--primary {
         color: #FFF;
         background-color: #409EFF;
         border-color: #409EFF;
     }
    .el-button--success {
        color: #FFF;
        background-color: #67C23A;
        border-color: #67C23A;
    }
    .el-button--danger {
        color: #FFF;
        background-color: #F56C6C;
        border-color: #F56C6C;
    }
    .el-button--warning {
        color: #FFF;
        background-color: #E6A23C;
        border-color: #E6A23C;
    }

    .cropper-content .show-preview .preview {
        margin-left: 0;
        -moz-user-select: none;
        -webkit-user-select: none;
        -ms-user-select: none;
        -khtml-user-select: none;
        user-select: none;
    }
</style>

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值