vue-cli3 + VueCropper解决裁剪图片问题

      公司项目作一个更换logo的功能,要求能够自定义裁剪图片,vueCopper能够实现,直接拿过来用,下面记录一下使用过程当中的问题。vue

      首先安装依赖:ajax

npm install vue-cropper@0.3.6复制代码

这里注意一下,我开始是直接安装的npm install vue-cropper,而后出现报错:npm

 Failed to mount component: template or render function not defined

好像是版本问题,而后查了一下 直接安装低版本的,好了api

        而后组件封装上代码:bash

<template>
    <div class="qn-copper">
        <div class="copper-contain">
            <div class="copper-contain-left">
                <vueCropper :img="option.img"
                    :canMoveBox='option.canMoveBox'
                    :centerBox='option.centerBox'
                    ref="cropper"
                    :original='option.original'
                    :outputSize="option.size"
                    :outputType="option.outputType"
                    :info="option.info"
                    :infoTrue='option.infoTrue'
                    :canScale="option.canScale"
                    :autoCrop="option.autoCrop"
                    :auto-crop-width="option.autoCropWidth"
                    :auto-crop-height="option.autoCropHeight"
                    :fixed="option.fixed"
                    :fixedBox="option.fixedBox"
                    :fixedNumber="option.fixedNumber"
                    @realTime="realTime"
                    @imgLoad="imgLoad"
                ></VueCropper>
            </div>
            <div class="copper-contain-right">
                <div class="show-preview">
                     <div :style="previews.div" class="preview">
                        <img :src="previews.url" :style="previews.img">
                    </div>
                </div>
                <div class="save-btn" @click="save">
                    保存
                </div>
            </div>
        </div>
        <div class="copper-operate">
            <label class="font_color">
                <span></span><span title='只容许上传图片或PDF'>上传</span> 
               <input  @change="upload_file($event,1)"  type="file"  
                       class="files" accept=".pdf,image/*">
            </label>
            <i class="el-icon-plus icon" @click='changeScale(1)'></i>
            <i class="el-icon-minus icon" @click='changeScale(-1)'></i>
            <i class="el-icon-refresh-left icon" @click='rotateLeft'></i>
            <i class="el-icon-refresh-right icon" @click="rotateRight"></i>
        </div>
     </div>
</template>
<script>
import VueCropper from 'vue-cropper'
import {oss_config_get,
        file_delete,
        file_update} from '../../../api/common_api.js'
export default {
    name:'qnCopper',
    components:{
        VueCropper,
    },
    props:{
        update_methods:'',设置logo的接口名称 由父组件传入
        update_data:{}       设置logo的接口数据格式
    },
    data(){
        return{
            option: {
                img: "/api/oss/proxy/logo/QQ图片20191030222607.jpg", // 裁剪图片的地址
                info: true, // 裁剪框的大小信息
                size: 1,
                outputSize: 0.8, // 裁剪生成图片的质量
                outputType: "png",// 裁剪生成图片的格式
                canScale: true, // 图片是否容许滚轮缩放
                autoCrop: true, // 是否默认生成截图框
                canMoveBox: true, // 截图框可否拖动
                // 只有自动截图开启 宽度高度才生效
                autoCropWidth: 300, // 默认生成截图框宽度
                autoCropHeight: 300, // 默认生成截图框高度
                // 开启宽度和高度比例
                fixed: true, // 是否开启截图框宽高固定比例
                fixedBox: true, // 固定截图框大小 不容许改变
                fixedNumber: [1, 1],// 截图框的宽高比例
                original: false, // 上传图片按照原始比例渲染
                centerBox: true, // 截图框是否被限制在图片里面
                infoTrue: true // true 为展现真实输出图片宽高 false 展现看到的截图框宽高
            },
            previews: {},
            ossConfig:'',
            fileName:'',            upkey:'',
        }
    },
    created(){
        this.config_init(); 
    },
    methods:{
        //阿里云文件上传服务初始化,不须要的不用
        config_init(){
            let timeStamp = Date.parse(new Date())/1000;
            // console.log(this.$store.state.ossConfig,'000000',timeStamp)
            if(timeStamp-this.$store.state.ossConfig.expire<60*60*24){
                this.ossConfig = this.$store.state.ossConfig;
            }else{
                this.ossConfig = oss_config_get();
            }
        },
        upload_file(e,num){
            let _this = this;
            //上传图片
             let file = e.target.files[0]
             _this.fileName = file.name;
            if (!/\.(gif|jpg|jpeg|png|bmp|GIF|JPG|PNG)$/.test(e.target.value)) {
                 this.$message({
                    message: '图片类型必须是.gif,jpeg,jpg,png,bmp中的一种',
                    type: 'warning' 
                  });
                return false
             }
             let reader = new FileReader();
             reader.onload =(e) => {
                 let data;
                 if (typeof e.target.result === 'object') {
                     // 把Array Buffer转化为blob 若是是base64不须要 
                    data = window.URL.createObjectURL(new Blob([e.target.result]))
                 } else {
                     data = e.target.result
                 }  
              if (num === 1) {
                     _this.option.img = data
              }
            }
             // 转化为base64
             // reader.readAsDataURL(file)
             // 转化为blob
             reader.readAsArrayBuffer(file);
        },
         // 实时预览函数
         realTime(data){
            this.previews = data
         },
        imgLoad(msg){
            console.log(msg)
        },
        //放大/缩小
        changeScale(num) {
            console.log('changeScale')
            num = num || 1;
            this.$refs.cropper.changeScale(num);
         },
         //坐旋转
        rotateLeft() {
             console.log('rotateLeft')
            this.$refs.cropper.rotateLeft();
         },
         //右旋转
        rotateRight() {
             console.log('rotateRight')
            this.$refs.cropper.rotateRight();
         }, 
        保存  先上传到文件服务器 而后调用设置logo接口 
       save(){
            let vue = this;
            let formData = new FormData();
            this.$refs.cropper.getCropBlob((data) => {
                 console.log(data)
                 let img = window.URL.createObjectURL(data)
                 console.log(img,'img')
                 let xmlhttp = new XMLHttpRequest();
                 formData.append('file', data,this.fileName);
                 let name = 'logo/' + (new Date()).valueOf();
                 formData.append('key', name);
                 for(let i in this.ossConfig){
                     formData.append(i,this.ossConfig[i])
                 }
                 xmlhttp.open("POST", '/api/oss/proxy' , true);
                 xmlhttp.onreadystatechange = function () {
                    if (xmlhttp.readyState == 4) {  
                       if (xmlhttp.status == 200) { 
                           let result = JSON.parse(xmlhttp.response);
                            if(result.code=='1'){
                                vue.update_parent(result.data.file)
                            }
                        } else {
                            vue.$message({message:'上传错误',type:'error'});
                        }
                    }
                }
                xmlhttp.upload.onprogress = function (event) {
                }
                xmlhttp.upload.onloadstart = function () {
                };
                xmlhttp.upload.onloadend = function () {
                };
                xmlhttp.onerror = function () {
                    vue.list_show();
                };
                xmlhttp.send(formData);
          })
         },
        设置logo接口
        update_parent(url){ 
           this.update_data.logoPic = url;
            this.update_methods(this.update_data).then(res=>{
                if(res.code == 1){
                    this.$message({message:'修改为功',type:'success'});
                }
            }).catch(err=>{
                console.log('ajax_err:',err)
            })
        }
    }}
</script>
<style lang="less" scoped>
.monitor-system{
    .qn-copper{
            }
}
.fireUnit-system{
      .qn-copper{
            }
 }
.fireSupUnit-system{
        //第三套央视
    .qn-copper{
        .font_color{
            color:#5E9BBA;
        }
    }
}
.qn-copper{
    width: 100%;
    height: 100%;
    .copper-contain{
        width: 100%; 
        height: 80%;
        display: flex;
        .copper-contain-left{
            width: 80%;
        }
        .copper-contain-right{
            margin-left: 30px;
            .show-preview{
                width: 150px;
                height: 150px;
                overflow: hidden;
            } 
           .save-btn{
                margin-top:20px;
                color:#24bbee;
                cursor: pointer;
                font-size: 15px;
            }
        }
    } 
   .copper-operate{
        color:#24bbee;
        margin-top: 10px;
        font-size: 15px;
        text-align: left;
        padding-left: 40px;
        box-sizing: border-box;
        .font_color{
            cursor: pointer;
            color:#24bbee;
            margin:0 20px;
        }
        .files{
            display: none;
        }
        .icon{
            margin:0 20px;
            font-size: 15px; 
           cursor: pointer;

         }
    }
}
</style>复制代码

效果以下:服务器


若有问题,欢迎探讨,若是满意,请手动点赞,谢谢!🙏
app

相关文章
相关标签/搜索