vue 项目 el-upload vue-cropper 上传图片自动裁剪功能

业务需要上传封面图 要求上传图片的大小 自己参考其他文章最后实现此功能,个人收藏
效果图
在这里插入图片描述

vue-cropper是一个可以进行图片剪辑的插件,使用于vue
github地址:https://github.com/xyxiao001/vue-cropper

1、下载vue-cropper
npm install vue-cropper

2、引用(组件引入)
import { VueCropper } from ‘vue-cropper’

3、component引入组件
components: {
VueCropper
},
主页面代码

//上传图片
<el-upload class="avatar-uploaderCss" :action="''" :headers="MyHeader" :show-file-list="false"  :before-upload="beforeAvatarUpload">
<img v-if="dataForm.coverImage" :src="dataForm.coverImage" class="avatar" />
<i v-else class="el-icon-plus avatar-uploader-icon"></i>

<!-- 裁剪功能 自己封装的组件 -->
//因为一个页面有多个上传图片 多个裁剪功能 所以用isXCropper的改变 组件监听变化 渲染调用组件
<XCropper ref="iscropper" :iscropperData="iscropperData" :isXCropper="isXCropper"  @getXCropper="getXCropper"></XCropper>
js
  // 裁剪功能组件引用
  import XCropper from "@/components/vueCropper"
  //上传
beforeAvatarUpload(file) {
        let _this = this
        return new Promise((resolve, reject) => {
          let types = ['image/jpeg', 'image/jpg', 'image/png'];
          const isJPG = types.includes(file.type)
          let imgType = file.type.split("/")[1]
          console.log('imgType', imgType)
           const isLt2M = file.size / 1024 / 1024 < 2
          if (!isJPG) {
            _this.$message.error('上传图片只能是 JPG 或 png格式!')
            reject()
          }
           if (!isLt2M) {
              _this.$message.error('上传图片大小不能超过 2MB!')
              reject()
           }


          let _URL = window.URL || window.webkitURL;

          _this.iscropperData = {
            img: _URL.createObjectURL(file), // 裁剪图片的地址
            autoCropWidth: 319, // 默认生成截图框宽度/2
            autoCropHeight: 158, // 默认生成截图框高度/2
            outputType: imgType,//图片格式
            fixedBox: true,
            dialogVisiblex: true,
            name: file.name,
            fileType: '2',
            file: file
          }
          this.isXCropper = true

        })
      },
     // 裁剪弹窗关闭后调用
     getXCropper(istype, file) {
        var that = this
        if (istype) {
          const cloneFile = new File([file.img], file.name);

          const formData = new FormData()
          formData.append('file', cloneFile)
          uploadFile(formData)
            .then(response => {
              //请求成功 不同的上传图片按钮调用不同的成功回调方法
              if(file.fileType=='2'){
                that.getsuccess(response.data, cloneFile)
              }else if(file.fileType=='3'){
                that.getsuccess2(response.data, cloneFile)
              }
              that.isXCropper = false
            }).catch(response => {
              that.$notify.error({
                title: "失败",
                message: response.data.msg
              });
            });
        } else {
          that.isXCropper = false
        }
      },
      //上传成功后图片回显
       getsuccess(e) {
        this.dataForm.coverImage = e.data;
        this.getValue();
      },

封装的组件

<template>
    <div class="vueCropperDIV">
        <el-dialog
                title="图片剪裁"
                :visible.sync="dialogVisiblex"
                v-model="dialogVisiblex"
                :close-on-press-escape="false"
                :close-on-click-modal="false"
                append-to-body
                width="1000px"
                @close="cancel"
        >
            <div style="margin-top: -30px;">
                <div class="cropper" style="text-align:center">
                    <vueCropper
                            ref="cropper"
                            :img="option.img"
                            :outputSize="option.outputSize"
                            :outputType="option.outputType"
                            :info="option.info"
                            :canScale="option.canScale"
                            :autoCrop="option.autoCrop"
                            :autoCropWidth="option.autoCropWidth"
                            :autoCropHeight="option.autoCropHeight"
                            :fixedBox="option.fixedBox"
                            :fixed="option.fixed"
                            :fixedNumber="option.fixedNumber"
                            :canMove="option.canMove"
                            :canMoveBox="option.canMoveBox"
                            :original="option.original"
                            :centerBox="option.centerBox"
                            :infoTrue="option.infoTrue"
                            :full="option.full"
                            :enlarge="option.enlarge"
                            :mode="option.mode"
                    >
                    </vueCropper>
                </div>
            </div>
           <div style="margin-top: 10px;"> 
            <el-button @click="cancel">取消</el-button>
            <el-button type="primary" @click="finish" :loading="loading">确认</el-button>
           </div>
                
        </el-dialog>
    </div>
</template>
 
<script>
 
// 局部引用
import {VueCropper} from 'vue-cropper'
    export default {
        components: { VueCropper },
        props: {
            //所有参数
            iscropperData:{
            type: '',
            default: null
            },
            //是否显示
            isXCropper:{
            type: Boolean,
            default: false
            },
        },
        data() {
            return {
                dialogVisiblex: true,
                loading: false,
                option: {
                    img: '', // 裁剪图片的地址 url 地址, base64, blob
                    outputSize: 1, // 裁剪生成图片的质量
                    outputType: 'jpeg', // 裁剪生成图片的格式 jpeg, png, webp
                    info: true, // 裁剪框的大小信息
                    canScale: true, // 图片是否允许滚轮缩放
                    autoCrop: true, // 是否默认生成截图框
                    autoCropWidth: 0, // 默认生成截图框宽度
                    autoCropHeight: 0, // 默认生成截图框高度
                    fixedBox: true, // 固定截图框大小 不允许改变
                    fixed: true, // 是否开启截图框宽高固定比例
                    fixedNumber: [1, 1], // 截图框的宽高比例 [ 宽度 , 高度 ]
                    canMove: true, // 上传图片是否可以移动
                    canMoveBox: true, // 截图框能否拖动
                    original: false, // 上传图片按照原始比例渲染
                    centerBox: true, // 截图框是否被限制在图片里面
                    infoTrue: true, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
                    full: true, // 是否输出原图比例的截图
                    enlarge: '1', // 图片根据截图框输出比例倍数
                    mode: 'contain' // 图片默认渲染方式 contain , cover, 100px, 100% auto
                },
                unimgurl: ''
            }
        },
        computed: {},
        watch: {
         isXCropper: {
            handler(newVal, oldVal) {
                this.getShowModal(this.iscropperData)
            },
            deep: true,
            immediate: true
            }
        },
        created() {
 
        },
        mounted() {  },
        activated() {},
        methods: {
            getShowModal(obj) {
                if (obj.img) {
                    this.option.img = obj.img
                }
                //裁剪生成图片的质量
                if (obj.outputSize) {
                    this.option.outputSize = obj.outputSize
                } else {
                    this.option.outputSize = 1
                }
                //裁剪生成图片的格式
                if (obj.outputType) {
                    this.option.outputType = obj.outputType
                } else {
                    this.option.outputType = 'jpeg'
                }
                //裁剪框的大小信息
                if (obj.info) {
                    this.option.info = obj.info
                } else {
                    this.option.info = true
                }
                //图片是否允许滚轮缩放
                if (obj.canScale) {
                    this.option.canScale = obj.canScale
                } else {
                    this.option.canScale = true
                }
                //是否默认生成截图框
                if (obj.autoCrop) {
                    this.option.autoCrop = obj.autoCrop
                } else {
                    this.option.autoCrop = true
                }
                //默认生成截图框宽度
                if (obj.autoCropWidth) {
                    this.option.autoCropWidth = obj.autoCropWidth
                } 
                //默认生成截图框高度
                if (obj.autoCropHeight) {
                    this.option.autoCropHeight = obj.autoCropHeight
                } 
                //固定截图框大小 不允许改变
                if (obj.fixedBox) {
                    this.option.fixedBox = obj.fixedBox
                } else {
                    this.option.fixedBox = false
                }
                //是否开启截图框宽高固定比例
                if (obj.fixed) {
                    this.option.fixed = obj.fixed
                } else {
                    this.option.fixed = true
                }
                //截图框的宽高比例
                if (obj.fixedNumber) {
                    this.option.fixedNumber = obj.fixedNumber
                } else {
                    this.option.fixedNumber = [this.option.autoCropWidth, this.option.autoCropHeight]
                }
                console.log('this.option.fixedNumber ',this.option.fixedNumber )
                //上传图片是否可以移动
                if (obj.canMove) {
                    this.option.canMove = obj.canMove
                } else {
                    this.option.canMove = true
                }
                //截图框能否拖动
                if (obj.canMoveBox) {
                    this.option.canMoveBox = obj.canMoveBox
                } else {
                    this.option.canMoveBox = true
                }
                //上传图片按照原始比例渲染
                if (obj.original) {
                    this.option.original = obj.original
                }
                //截图框是否被限制在图片里面
                if (obj.centerBox) {
                    this.option.centerBox = obj.centerBox
                } else {
                    this.option.centerBox = true
                }
                //true 为展示真实输出图片宽高 false 展示看到的截图框宽高
                if (obj.infoTrue) {
                    this.option.infoTrue = obj.infoTrue
                } else {
                    this.option.infoTrue = true
                }
                //是否输出原图比例的截图
                if (obj.full) {
                    this.option.full = obj.full
                } else {
                    this.option.full = true
                }
                //图片根据截图框输出比例倍数
                if (obj.enlarge) {
                    this.option.enlarge = obj.enlarge
                } else {
                    this.option.enlarge = '1'
                }
                //图片默认渲染方式
                if (obj.mode) {
                    this.option.mode = obj.mode
                } else {
                    this.option.mode = 'contain'
                }
                this.dialogVisiblex = this.isXCropper
                console.log('this.dialogVisiblex0',this.dialogVisiblex)
            },
            finish() {
                // 获取截图的数据
                let that = this
                this.$refs.cropper.getCropBlob(data => {
                    that.unimgurl = data
                    that.confirm()
                })
            },
            confirm() {
                var data={ img: this.unimgurl,
                    name:this.iscropperData.name,
                    fileType:this.iscropperData.fileType,
                    file:this.iscropperData.file
                }
                this.dialogVisiblex = false
                 //参数传给父级
                this.$emit("getXCropper",true,data)
            },
            cancel() {
                this.dialogVisiblex = false
                 //参数传给父级
                this.$emit("getXCropper",false)
            }
        }
    }
</script>
<style lang="scss">
    .real_info_class {
        .el-checkbox__input .el-checkbox__inner {
            border-radius: 0;
        }
    }
    .file-image {
        width: 320px;
        height: 320px;
        font-size: 14px;
        border: 1px solid #cccccc;
        margin: 15px 0;
    }
 
    .cropper {
        width: 960px;
        height: 606px;
    }
</style>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Vue中,你可以结合`element-ui`的`el-upload`组件和`vue-cropper`库来实现图片上传和裁剪功能。以下是一个基本的步骤: 1. 安装依赖: 首先,你需要安装这两个库,如果你还没有安装,可以在项目目录下运行: ```bash npm install element-ui vue-cropper ``` 2. 引入组件: 在你的Vue文件中,引入这两个组件: ```javascript import { ElUpload } from 'element-ui'; import VueCropper from 'vue-cropper'; ``` 3. 在模板中使用`el-upload`和`vue-cropper`: ```html <template> <div> <el-upload :action="uploadUrl" :on-success="handleSuccess" :on-change="handleChange" :before-upload="beforeUpload" ref="upload" > <el-button size="small" type="primary">点击选择图片</el-button> </el-upload> <vue-cropper ref="cropper" :img-url="croppedImageUrl" :output-type="outputType"></vue-cropper> </div> </template> ``` 4. 编写方法: - `handleSuccess(response, file)`:处理上传成功后的回调,这里可以更新`croppedImageUrl`。 - `handleChange(file)`:处理文件变化,可以预览图片并显示到cropper组件中。 - `beforeUpload(file)`:在上传前的钩子,可以在这里做些验证或处理。 5. 数据绑定: ```javascript data() { return { uploadUrl: 'your-upload-url', croppedImageUrl: '', outputType: 'image/jpeg', // 可选类型:image/jpeg, image/png, image/webp }; }, methods: { handleSuccess(response, file) { // 在这里处理上传成功的响应并更新croppedImageUrl this.croppedImageUrl = response.data.url; }, handleChange(file) { this.$refs.upload.fileList = file; // 将文件信息传递给cropper this.$refs.cropper.src = file.url; // 设置cropper的图片源 }, beforeUpload(file) { // 这里可以根据需求检查文件大小、类型等 } } ``` 注意替换`your-upload-url`为你实际的图片上传地址。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值