zoukankan      html  css  js  c++  java
  • 在vue中使用vue-cropper图片裁剪并上传图片(配合ant-design-vue的upload组件)

    在vue中使用vue-cropper图片裁剪并上传图片

    思路:封装一个对话框(Modal),里面包含一个vue-cropper,用于ant-upload上传文件时调用弹出此对话框让用户编辑此图片.裁剪完emit一个事件,然后上传这个编辑后的图片(file)

    先是对vue-cropper进行再封装

    该组件就对外''暴露 "2个操作 1. 传入图像数据并打开对话框 2. 图像处理完后返回图像数据 这使用起来方便

    码来:srccomponentscommoncropper-modal.vue

    <template>
      <a-modal
        :visible="visible"
        title="请裁剪图片"
        :maskClosable="false"
        :confirmLoading="confirmLoading"
        @cancel="handleCancel"
        @ok="handleOk"
      >
        <div class="cropper-wrapper">
          <vue-cropper
            ref="cropper"
            :img="img"
            :info="true"
            :original="true"
            :autoCrop="options.autoCrop"
            :autoCropWidth="options.autoCropWidth"
            :autoCropHeight="options.autoCropHeight"
            :fixedBox="options.fixedBox"
          ></vue-cropper>
        </div>
      </a-modal>
    </template>
    
    <script>
    import { VueCropper } from 'vue-cropper'
    export default {
      components: {
        VueCropper,
      },
      data() {
        return {
          // ant-modal相关配置
          visible: false,
          confirmLoading: false,
          // vue-cropper相关配置 详细的可以去github上看文档
          img: null, //要裁剪的图像资源 可选项: url地址 || base64 || blob
          options: {
            autoCrop: true, //是否默认生成截图框
            autoCropWidth: 200, //默认生成截图框宽度
            autoCropHeight: 200, //默认生成截图框高度
            fixedBox: true, //固定截图框大小 不允许改变
          },
        }
      },
      methods: {
        // 调用此方法需传入一个 [url地址 || base64 || blob]
        // 父组件调用: this.$refs['cropperModal'].edit(参数)
        edit(image) {
          this.img = image
          this.visible = true
        },
        // 监听对话框的OK/Cancel按钮的点击事件
        handleOk() {
          const that = this
          that.confirmLoading = true
          // 获取截图的base64 数据
          // getCropBlob获取二进制数据
          this.$refs.cropper.getCropData((data) => {
            //将裁剪侯后的图片对象射给**父组件**,然后关闭对话框
            that.$emit('ok', data)
            that.handleCancel()
          })
        },
        handleCancel(e) {
          this.visible = false
        },
      },
    }
    </script>
    
    <style lang="scss" scoped>
    .cropper-wrapper {
       100%;
      height: 400px;
    }
    </style>
    

    父组件是用了ant-design-vue的upload组件

    关键代码如下:显示为一个按钮,点击更换头像后弹出文件选择框,再选择文件后先是调用beforeUpload判断文件类型,满足条件然后调用

    handleUploadChange函数

    @ok="handleOK"就是在图片裁剪后 emit的ok事件

            <a-upload
              :before-upload="beforeUpload"
              :show-upload-list="false"
              :custom-request="function(){}"
              @change="handleUploadChange"
            >
              <a-button type="primary">更换头像</a-button>
            </a-upload>
    
    <cropper-modal @ok="handleOK" ref="cropperModal" />
    
    	// 在父组件的methods中   
    
    	// 选择文件后且beforeUpload返回为true后会调用这个方法
        handleUploadChange(info) {
          // 这个回调函数的参数是个File对象,所以要用FileReader将对象转换成 data-uri (base64) 对象,才能给vue-cropper
          var reader = new FileReader()
          const _this = this
          // 当文件处理完成的回调函数
          reader.onload = function (e) {
            // e.target.result 该属性表示目标对象的DataURL
            // 然后调用cropperModal的edit方法使得对话框可见
            _this.$refs['cropperModal'].edit(e.target.result)
          }
         // 记录原始的文件名字,用于DataURL(base64)转成file对象,不转就可以不用
          this.tmpImgName = info.file.name
         // 文件处理 file=>base64 
          reader.readAsDataURL(info.file.originFileObj)
        },
    	
        // 对文件格式校验(ant-upload选择文件框是所有类型的)   
        beforeUpload(file) {
            var fileType = file.type
            console.log(file.type)
            if (fileType.indexOf('image') < 0) {
                this.$message.warning('请上传图片')
                return false
            }
        },
            
     // 然后这里可以调用api请求上传图片
      handleOK(data) {
          console.log(data)
          let file = this.dataURLtoFile(data, this.tmpImgName)
          console.log(file)
    	 // ....省略api请求 2种格式的对象都拿到了 怎么请求不用说了吧
        },
            
    // 将base64转换为文件 百度随便找的 看需求使用
        dataURLtoFile(dataurl, filename) {
          var arr = dataurl.split(','),
            mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]),
            n = bstr.length,
            u8arr = new Uint8Array(n)
          while (n--) {
            u8arr[n] = bstr.charCodeAt(n)
          }
          return new File([u8arr], filename, { type: mime })
        },
            
    

    附带一个axios上传multipart格式的文件方法

      // 上传头像 File类型
      uploadAvatar(file) {
        let param = new FormData()  // 创建form对象
        param.append('file', file)  // 通过append向form对象添加数据
        // param.append('chunk', '0') // 添加form表单中其他数据
        let config = {
          headers: { 'Content-Type': 'multipart/form-data' }
        }
        return axios.post('/upload/avatar', param, config)
      },
    

    参考链接

    文档教程:http://github.xyxiao.cn/vue-cropper/example/

    他人教程:https://www.jianshu.com/p/4024cf503380

    结合antv:https://blog.csdn.net/qq_36111804/article/details/94599536

    HTML5 file对象和blob对象的互相转换 https://www.jianshu.com/p/5b44c41adfe2

  • 相关阅读:
    微信小程序 选择图片 并上传到服务器
    微信小程序 setData
    python--字典排序
    python--csv文件读写
    机器学习实战笔记--AdaBoost(实例代码)
    机器学习实战笔记--朴素贝叶斯(实例代码)
    python继承 super()
    机器学习实战笔记—决策树(代码讲解)
    java的基本认识
    Delphi制作DLL
  • 原文地址:https://www.cnblogs.com/somegenki/p/13523374.html
Copyright © 2011-2022 走看看