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 router安装及使用方法解析
Dec 02 Vue.js
Vue 修改网站图标的方法
Dec 31 Vue.js
vue 动态生成拓扑图的示例
Jan 03 Vue.js
vue3弹出层V3Popup实例详解
Jan 04 Vue.js
Vue+scss白天和夜间模式切换功能的实现方法
Jan 05 Vue.js
Vue中的nextTick作用和几个简单的使用场景
Jan 25 Vue.js
Vue 数据响应式相关总结
Jan 28 Vue.js
详解Vue.js 可拖放文本框组件的使用
Mar 03 Vue.js
Vue.js 带下拉选项的输入框(Textbox with Dropdown)组件
Apr 17 Vue.js
vue3获取当前路由地址
Feb 18 Vue.js
分享一个vue实现的记事本功能案例
Apr 11 Vue.js
vue-cli3.x配置全局的scss的时候报错问题及解决
Apr 30 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
phpmyadmin操作流程
2006/10/09 PHP
一个MYSQL操作类
2006/11/16 PHP
用PHP实现Ftp用户的在线管理的代码
2007/03/06 PHP
PHP MemCached 高级缓存应用代码
2010/08/05 PHP
解析二进制流接口应用实例 pack、unpack、ord 函数使用方法
2013/06/18 PHP
php获取目录所有文件并将结果保存到数组(实例)
2013/10/25 PHP
PHP文件读取功能的应用实例
2015/05/08 PHP
PHP使用Mysqli类库实现完美分页效果的方法
2016/04/07 PHP
php实现的rc4加密解密类定义与用法示例
2018/08/16 PHP
JS查看对象功能代码
2008/04/25 Javascript
javascript Split方法,indexOf方法、lastIndexOf 方法和substring 方法
2009/03/21 Javascript
两个select多选模式的选项相互移动(示例代码)
2014/01/11 Javascript
Jquery实现的一种常用高亮效果示例代码
2014/01/28 Javascript
jQuery制作简单柱状图实例
2015/01/28 Javascript
微信小程序 this和that详解及简单实例
2017/02/13 Javascript
使用Fullpage插件快速开发整屏翻页的页面
2017/09/13 Javascript
详解微信小程序-扫一扫 wx.scanCode() 扫码大变身
2019/04/30 Javascript
在NodeJs中使用node-schedule增加定时器任务的方法
2020/06/08 NodeJs
vue实现移动端触屏拖拽功能
2020/08/21 Javascript
[51:53]DOTA2-DPC中国联赛 正赛 RNG vs Dragon BO3 第二场 1月24日
2021/03/11 DOTA
在Python中操作列表之list.extend()方法的使用
2015/05/20 Python
举例讲解Python设计模式编程中的访问者与观察者模式
2016/01/26 Python
Python实现把类当做字典来访问
2019/12/16 Python
英国排名第一的最新设计师品牌手表独立零售商:TIC Watches
2016/09/24 全球购物
生物科学系大学生的自我评价
2013/12/20 职场文书
农贸市场管理制度
2014/01/31 职场文书
2014年幼儿园植树节活动方案
2014/03/02 职场文书
外贸员简历中的自我评价
2014/03/04 职场文书
淘宝好评语大全
2014/05/05 职场文书
森林病虫害防治方案
2014/06/02 职场文书
新教师培训方案
2014/06/08 职场文书
反四风个人对照检查材料思想汇报
2014/09/25 职场文书
迎新晚会主持词开场白
2015/05/28 职场文书
2016年国庆节67周年活动总结
2016/04/01 职场文书
Windows11性能真的上涨35%? 桌面酷睿i9实测结果公开
2021/11/21 数码科技
VUE递归树形实现多级列表
2022/07/15 Vue.js