vue-cropper插件实现图片截取上传组件封装


Posted in Vue.js onMay 27, 2021

基于vue-cropper插件实现图片截取上传组件封装的具体代码,供大家参考,具体内容如下

需求场景:

后台开发需要上传图片并进行相应比例尺寸图片的截取,本组件开发采用Ant Design Vue组件库搭配vue-cropper插件进行封装

实现如下

vue-cropper插件实现图片截取上传组件封装

vue-cropper插件实现图片截取上传组件封装

html

<template>
  <div>
    <a-upload
      name="avatar"
      list-type="picture-card"
      class="avatar-uploader"
      :show-upload-list="false"
      :custom-request="customRequest"
      :before-upload="beforeUpload"
      :style="`width: ${width}; height: ${height};`"
    >
      <img
        v-if="imageUrl && !loading"
        :src="imageUrl"
        alt="avatar"
        :style="`width: ${width}; height: ${height};`"
      />
      <div v-else>
        <a-icon :type="loading ? 'loading' : 'plus'" />
        <div class="ant-upload-text">上传图片</div>
      </div>
    </a-upload>
    <a-modal
      v-model="imageCut.isShowModal"
      title="图片截取"
      width="400px"
      @ok="finish"
      @cancel="imageCut.close"
    >
      <div class="cropper-content" v-if="imageCut.isShowModal">
        <div class="cropper" style="text-align:center">
          <vueCropper
            ref="cropper"
            :img="imageCut.imgFile"
            :outputSize="outputSize"
            :outputType="outputType"
            :info="info"
            :full="full"
            :canMove="canMove"
            :canMoveBox="canMoveBox"
            :original="original"
            :autoCrop="autoCrop"
            :fixed="fixed"
            :fixedNumber="fixedNumber"
            :centerBox="centerBox"
            :infoTrue="infoTrue"
            :fixedBox="fixedBox"
          ></vueCropper>
        </div>
      </div>
    </a-modal>
  </div>
</template>

js

<script>
import { uploadImage } from '@/api/common'
import { VueCropper } from "vue-cropper";
export default {
  name: 'ImageUpload',
  components: { VueCropper },
  data() {
    return {
      loading: false,
      imageCut: {
        isShowModal: false,
        imgFile: '',
        init: imgFile => {
          this.imageCut.imgFile = imgFile
          this.imageCut.isShowModal = true
        },
        close: () => {
          this.imageCut.imgFile = ''
          this.imageCut.isShowModal = false
        }
      }
    }
  },
  props: {
    imageUrl: String,
    width: {
      type: String,
      default: '100px'
    },
    height: {
      type: String,
      default: '100px'
    },
    canCut: {
      type: Boolean,
      default: false
    },
    info: {
      type: Boolean,
      default: false
    }, // 裁剪框的大小信息
    outputSize: {
      type: Number,
      default: 0.8
    }, // 裁剪生成图片的质量
    outputType: {
      type: String,
      default: 'jpeg'
    }, // 裁剪生成图片的格式
    canScale: {
      type: Boolean,
      default: true
    }, // 图片是否允许滚轮缩放
    autoCrop: {
      type: Boolean,
      default: true
    }, // 是否默认生成截图框
    // autoCropWidth: 300, // 默认生成截图框宽度
    // autoCropHeight: 200, // 默认生成截图框高度
    fixedBox: {
      type: Boolean,
      default: false
    }, // 固定截图框大小 不允许改变
    fixed: {
      type: Boolean,
      default: true
    }, // 是否开启截图框宽高固定比例
    fixedNumber: {
      type: Array,
      default: () => [1, 1]
    }, // 截图框的宽高比例
    full: {
      type: Boolean,
      default: true
    }, // 是否输出原图比例的截图
    canMove: {
      type: Boolean,
      default: false
    },
    canMoveBox: {
      type: Boolean,
      default: true
    }, // 截图框能否拖动
    original: {
      type: Boolean,
      default: false
    }, // 上传图片按照原始比例渲染
    centerBox: {
      type: Boolean,
      default: true
    }, // 截图框是否被限制在图片里面
    infoTrue: {
      type: Boolean,
      default: true
    } // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
  },
  methods: {
    beforeUpload(file) {
      const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'
      if (!isJpgOrPng) {
        this.$message.error('请上传JPG或PNG文件!')
      }
      const isLt2M = file.size / 1024 / 1024 < 2
      if (!isLt2M) {
        this.$message.error('请上传2MB以下文件!')
      }
      return isJpgOrPng && isLt2M
    },
    customRequest(file) {
      if (this.canCut) {
        this.readFile(file.file)
      } else {
        this.loading = true
        const formData = new FormData()
        formData.append('fileIdcard', file.file)
        uploadImage(formData).then(res => {
          this.loading = false
          this.$emit('uploadSuccess', res.ossUrl)
        })
      }
    },
    readFile(file) {
      var reader = new FileReader()
      reader.readAsDataURL(file)
      reader.onload = () => {
        this.imageCut.init(reader.result)
      }
    },
    finish() {
      this.$refs.cropper.getCropBlob(data => {
        this.loading = true
        // 上传阿里云服务器
        const formData = new FormData()
        formData.append('fileIdcard', data)
        uploadImage(formData).then(res => {
          this.imageCut.close()
          this.loading = false
          this.$emit('uploadSuccess', res.ossUrl)
        })
      })
    }
  }
}
</script>

css

<style lang="less">
.avatar-uploader > .ant-upload {
  width: 100%;
  height: 100%;
}
.ant-upload-select-picture-card i {
  font-size: 32px;
  color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
  margin-top: 8px;
  color: #666;
}
.cropper-content {
  .cropper {
    width: auto;
    height: 400px;
  }
}
</style>

组件使用及说明

<image-upload
        :imageUrl="form.diagramUrl"
        @uploadSuccess="uploadSuccess"
        width="160px"
        height="90px"
        :can-edit="canCut"
        :fixed-number="[16,9]"
      />

组件调用时需传入canEdit属性,指定组件是否启动图片选取后的裁剪功能,默认值为不启用裁剪;需裁剪时可传入fixedNumber属性,定义裁剪框的宽高比

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Vue.js 相关文章推荐
vue表单验证之禁止input输入框输入空格
Dec 03 Vue.js
Vue 修改网站图标的方法
Dec 31 Vue.js
vue实现登录功能
Dec 31 Vue.js
vue实现按钮切换图片
Jan 20 Vue.js
Vue 集成 PDF.js 实现 PDF 预览和添加水印的步骤
Jan 22 Vue.js
vue-video-player 断点续播的实现
Feb 01 Vue.js
vue中axios封装使用的完整教程
Mar 03 Vue.js
Vue3 Composition API的使用简介
Mar 29 Vue.js
一文带你理解vue创建一个后台管理系统流程(Vue+Element)
May 18 Vue.js
vue实现锚点定位功能
Jun 29 Vue.js
Vue Mint UI mt-swipe的使用方式
Jun 05 Vue.js
HTML+VUE分页实现炫酷物联网大屏功能
Vue实现动态查询规则生成组件
详解vue身份认证管理和租户管理
vue点击弹窗自动触发点击事件的解决办法(模拟场景)
vue-element-admin项目导入和导出的实现
May 21 #Vue.js
vue2实现provide inject传递响应式
May 21 #Vue.js
vue使用节流函数的踩坑实例指南
You might like
PHP面向对象编程快速入门
2006/10/09 PHP
解析PHP 使用curl提交json格式数据
2013/06/29 PHP
php5.2 Json不能正确处理中文、GB编码的解决方法
2014/03/28 PHP
CodeIgniter实现从网站抓取图片并自动下载到文件夹里的方法
2015/06/17 PHP
ThinkPHP在Cli模式下使用模板引擎的方法
2015/09/25 PHP
php时间函数用法分析
2016/05/28 PHP
PHP调试及性能分析工具Xdebug详解
2017/02/09 PHP
PHP开发中解决并发问题的几种实现方法分析
2017/11/13 PHP
PhpStorm+xdebug+postman调试技巧分享
2020/09/15 PHP
JQuery 无废话系列教程(一) jquery入门 [推荐]
2009/06/23 Javascript
javascript学习基础笔记之DOM对象操作
2011/11/03 Javascript
javascript在myeclipse中报错的解决方法
2013/10/29 Javascript
Javascript改变CSS样式(局部和全局)
2013/12/18 Javascript
用html5 js实现点击一个按钮达到浏览器全屏效果
2014/05/28 Javascript
使用jquery提交form表单并自定义action的方法
2016/05/25 Javascript
JavaScript必知必会(五) eval 的使用
2016/06/08 Javascript
利用jsonp跨域调用百度js实现搜索框智能提示
2016/08/24 Javascript
详谈jQuery.load()和Jsp的include的区别
2017/04/12 jQuery
Vue报错:Uncaught TypeError: Cannot assign to read only property’exports‘ of object’#‘的解决方法
2017/06/17 Javascript
限时抢购-倒计时的完整实例(分享)
2017/09/17 Javascript
vue+vuecli+webpack中使用mockjs模拟后端数据的示例
2017/10/24 Javascript
微信小程序wx.getImageInfo()如何获取图片信息
2018/01/26 Javascript
简单使用webpack打包文件的实现
2019/10/29 Javascript
[59:15]EG vs LGD 2018国际邀请赛淘汰赛BO3 第一场 8.26
2018/08/29 DOTA
Python学习资料
2007/02/08 Python
举例讲解Python编程中对线程锁的使用
2016/07/12 Python
Python开发虚拟环境使用virtualenvwrapper的搭建步骤教程图解
2018/09/19 Python
python将处理好的图像保存到指定目录下的方法
2019/01/10 Python
python argparse传入布尔参数false不生效的解决
2020/04/20 Python
CSS3 3D旋转rotate效果实例介绍
2016/05/03 HTML / CSS
财政专业大学生职业生涯规划书
2014/09/17 职场文书
社区党建工作总结2015
2015/05/13 职场文书
军训决心书范文
2015/09/22 职场文书
2016年大学生实习单位评语
2015/12/01 职场文书
导游词之舟山普陀山
2019/11/06 职场文书
JDBC连接的六步实例代码(与mysql连接)
2021/05/12 MySQL