zoukankan      html  css  js  c++  java
  • vue-cropperjs 插件的组件化使用 前端裁剪插件 vue

    vue-cropperjs 插件的组件化使用

    安装

    npm install --save vue-cropperjs   或者 cnpm install --save vue-cropperjs
    

    局部引入

    import VueCropper from 'vue-cropperjs'
    export default {
      components: { VueCropper },
    

    组件内容

      <div>
        <div class="crop-demo">
          <div class="crop-demo-btn" v-show="false">
            点击更换图片
            <input class="crop-input" type="file" name="image" accept="image/*" @change="setImage" id="change" />
          </div>
        </div>
        <el-dialog :append-to-body="true" title="图片剪裁" :visible.sync="dialogVisible" :close-on-click-modal="false" width="40%">
          <vue-cropper :aspect-ratio="cropperAspectWH" ref="cropper" :src="imgSrc" :ready="cropImage" :zoom="cropImage" :cropmove="cropImage" style=" 100%; height: 300px"></vue-cropper>
          <span slot="footer" class="dialog-footer">
            <el-button @click="cancelCrop">取 消</el-button>
            <el-button type="primary" @click="upladPic">确 定</el-button>
          </span>
        </el-dialog>
        <div v-show="false">{{ thisAspectWH }}</div>
      </div>
    </template>
    
    <script>
    import VueCropper from 'vue-cropperjs'
    export default {
      components: { VueCropper },
      props: ['label', 'AspectWH'],//label 是父组件传的标识符 (用于一个页面内多处使用裁剪组件,裁剪结果返回值错乱)   AspectWH 是用于限定裁剪框的比例的1为1:1  可传null则是不限制(注意传值是否为字符串)
      data() {
        return {
          //以下都是截图插件的
          imgSrc: '',
          dialogVisible: false,
          img_size: '',
          max_fuyuan_defaultSrc: [],
          cropperAspectWH: 1, //图片剪裁宽高比例
          reader: '',
          e_photo_file: '',
          e_photo_filefile: '',
          http_cropImg: '', //带http
          cropImg: '', //默认图片不带http
        }
      },
      methods: {
        //监听父组件是否点击上传的事件
        childAction() {
          $('#change').click()
        },
        //向父组件发送数据  cropImg 裁剪得到的图片名称  http_cropImg 带域名的图片名称  label就是传进来的标识符,也带着传出去
        sendMsg() {
          this.$emit('getPicNamefile', this.cropImg, this.http_cropImg, this.label)
        },
        /******************************图片剪切开始****************************************/
        setImage(e) {
          let that = this
          this.e_photo_file = e
          let file = e.target.files[0]
          this.e_photo_filefile = file
          if (!file.type.includes('image/')) {
            return
          }
          this.reader = ''
          let canvas = '',
            ctx = '',
            img = ''
    
          this.imgSrc = ''
          this.reader = new FileReader()
          this.reader.onload = (event) => {
            if (file.size >= 1024 * 1024 * this.GLOBAL.fileSize) {
              //调用自定义方法来处理图片
              var quality = 1 //压缩图片的质量
              canvas = document.createElement('canvas') //创建画布
              ctx = canvas.getContext('2d')
              img = new Image()
              img.src = event.target.result
              img.onload = function () {
                const width = img.width
                const height = img.height
                canvas.width = 1200 //这里可以自定义你的图片大小
                canvas.height = 1200 * (img.height / img.width)
                that.dialogVisible = true
                setTimeout(() => {
                  ctx.fillRect(0, 0, 0, 0)
                  ctx.drawImage(img, 0, 0, 1200, canvas.height)
                  that.imgSrc = canvas.toDataURL('image/jpeg', quality) //将图片转为Base64 之后预览要用
                  that.$refs.cropper.replace(that.imgSrc)
                }, 50)
              }
            } else {
              that.dialogVisible = true
              that.$nextTick(function () {
                that.imgSrc = event.target.result
                that.$refs.cropper.replace(event.target.result)
              })
            }
          }
          that.reader.readAsDataURL(file)
        },
        setImage_two(e) {
          let that = this
          let file = this.e_photo_filefile
          let canvas = '', ctx = '',img = '';
          this.e_photo_file = e
          this.e_photo_filefile = file
          this.reader = ''
          this.imgSrc = ''
          this.reader = new FileReader()
          this.reader.onload = (event) => {
            //调用自定义方法来处理图片
            var quality = 1 //压缩图片的质量
            canvas = document.createElement('canvas') //创建画布
    
            ctx = canvas.getContext('2d')
    
            img = new Image()
            img.src = event.target.result
            img.onload = function () {
              // 清除画布
              const width = img.width
              const height = img.height
              canvas.width = 1200 //这里可以自定义你的图片大小
              canvas.height = 1200 * (img.height / img.width)
              setTimeout(() => {
                ctx.fillRect(0, 0, 0, 0)
                ctx.drawImage(img, 0, 0, 1200, canvas.height)
    
                that.imgSrc = canvas.toDataURL('image/jpeg', quality) //将图片转为Base64 之后预览要用
                that.$refs.cropper && that.$refs.cropper.replace(that.imgSrc)
              }, 50)
            }
          }
          that.reader.readAsDataURL(file)
        },
        cropImage() {
          this.http_cropImg = this.$refs.cropper.getCroppedCanvas().toDataURL()
        },
        cancelCrop() {
          this.dialogVisible = false
          this.http_cropImg = this.max_fuyuan_defaultSrc[this.max_fuyuan_defaultSrc.length - 1]
          $('#change').val('') //取消change事件
        },
        upladPic() {
          this.sumitImageFile(this.http_cropImg)
        },
        sumitImageFile(base64Codes) {
          let that = this
          var formData = new FormData()
          var picName = new Date().getTime() + '.png' //给截图的文件命名
          formData.append('file', that.convertBase64UrlToBlob(base64Codes), picName) //append函数的第一个参数是后台获取数据的参数名,和html标签的input的name属性功能相同
    
          if (this.img_size >= 1024 * 1024 * this.GLOBAL.fileSize) {
            this.$message({
              message: '要上传图片太大,请再次截取,本次截取将进行压缩处理!',
              type: 'warning',
            })
            this.setImage_two(that.e_photo_file)
            return
          }
          if (this.img_size / 1024 / 1024 < this.GLOBAL.fileSize) {
            serviceApi.requestPostUploadFile(formData).then((body) => {
              that.cropImg = body.file_name
              //传递给父组件
    
              that.sendMsg()
            })
          } else {
            this.$message({
              message: '抱歉,要上传图片太大,请重新上传!',
              type: 'warning',
            })
            that.cropImg = ''
            that.http_cropImg = ''
            //传给表单
            //传递给父组件
            that.cropper_show = false
            that.sendMsg()
          }
          //关闭弹框
          $('#change').val('') //取消change事件
          this.dialogVisible = false
        },
        //将以base64的图片url数据转换为Blob
        convertBase64UrlToBlob(urlData) {
          var bytes = window.atob(urlData.split(',')[1]) //去掉url的头,并转换为byte
          //处理异常,将ascii码小于0的转换为大于0
          var ab = new ArrayBuffer(bytes.length)
          var ia = new Uint8Array(ab)
          for (let i = 0; i < bytes.length; i++) {
            ia[i] = bytes.charCodeAt(i)
          }
          let size = new Blob([ab], { type: 'image/png' })
          this.img_size = size.size
          return new Blob([ab], { type: 'image/png' })
        },
        /******************************图片剪切结束****************************************/
      },
      computed: {
        thisAspectWH() {
          if (this.AspectWH) {
            this.cropperAspectWH = this.AspectWH
          }
        },
      },
      mounted() {
        //监听父组件是否点击上传的事件
        this.$on('inputfile', (val) => {
          if (this.AspectWH) {
            this.cropperAspectWH = this.AspectWH
          }
          this.childAction(val)
        })
      },
      watch: {},
      created() {
        if (this.AspectWH) {
          this.cropperAspectWH = this.AspectWH
        }
      },
    }
    </script>
    
    
    <style scoped>
    /* 图片剪裁样式 */
    .crop-demo {
      display: flex;
      align-items: flex-end;
       150px;
      height: 150px;
    }
    .crop-demo-btn {
      position: absolute;
      left: auto;
      top: 50%;
      transform: translateY(-50%);
       100px;
      height: 40px;
      line-height: 40px;
      padding: 0;
      text-align: center;
      font-size: 12px;
      margin-left: 25px;
      color: #fff;
      background-color: rgba(0, 0, 0, 0.2);
      border-radius: 4px;
      box-sizing: border-box;
      cursor: pointer;
    }
    .crop-input {
      position: absolute;
       100px;
      height: 40px;
      left: 0;
      top: 0;
      opacity: 0;
      font-size: 0;
      padding: 0;
      cursor: pointer;
    }
    </style>
    
    

    注意点

    这个方法要自己写 serviceApi.requestPostUploadFile

    父组件中使用

     <div class="crop-demo">
                    <div
                      style="
                        position: relative;
                        display: flex;
                         340px;
                        height: 170px;
                      "
                    >
                      <span>
                        <img
                          :src="XXXXXXX"
                          style="
                             340px;
                            height: 170px;
                            background: #f8f8f8;
                            border: 1px solid #eee;
                            border-radius: 5px;
                            object-fit: cover;
                          "
                        />
                      </span>
                      <div
                        style="
                          position: absolute;
                          left: 50%;
                          top: 50%;
                          transform: translate(-50%, -50%);
                           100px;
                          line-height: 40px;
                          padding: 0;
                          text-align: center;
                          font-size: 12px;
                          background-color: #9da1a585;
                          color: #fff;
                          border-radius: 4px;
                          box-sizing: border-box;
                        "
                      >
                        点击更换图片
                        <div
                          @click="toSonClick('label')"
                          style="
                            position: absolute;
                             100px;
                            height: 40px;
                            left: 0;
                            top: 0;
                            opacity: 0;
                            cursor: pointer;
                          "
                        />
                      </div>
                    </div>
                  </div>
        <CropperCut
          v-if="CropperCutShow"
          :AspectWH="AspectWH"
          :label="CropperCutlabel"
          @getPicNamefile="getPicNamefile"
          ref="CropperCut"
        ></CropperCut>
    
        data中加入:
          //裁剪插件的label   是谁调用的
          AspectWH: "1", //裁剪插件的宽高比
          CropperCutlabel: "",
          CropperCutShow: false, //控制开关 裁剪插件
    
    
      //裁剪插件的事件
        toSonClick(label) {
          let that = this;
          if (label == "label") {
            this.AspectWH = 1;
          } else if (label == "XXX") {
            this.AspectWH = 2;
          }
          this.CropperCutShow = true;
          this.CropperCutlabel = label;
          setTimeout(() => {
            that.$refs.CropperCut.$emit("inputfile");
          }, 10);
        },
        //插件插件
        getPicNamefile(cropImg, http_cropImg, label) {
          this.CropperCutShow = false;
          this.AspectWH = 1;
          if (label == "label") {
            this.CropperCutlabel = "";
          } else if (label == "XXX") {
            this.CropperCutlabel = "";
          }
        },
    

    **插件官网:https://www.npmjs.com/package/vue-cropperjs

  • 相关阅读:
    Flask request接口获取参数
    python踩坑系列之导入包时下划红线及报错“No module named”问题
    报表测试方法与注意事项
    如何查看队列被某个应用消费
    Jinkins自动构建
    Python3字典排序
    【Win10】【译】提交 UWP 应用时遇到意料之外的语言?
    【Win10】探索 Windows 10 10586 之 JumpList(跳转列表)
    【Win10】页面导航的实现
    【Win10】使用 ValidationAttribute 实现数据验证
  • 原文地址:https://www.cnblogs.com/panghu123/p/14973810.html
Copyright © 2011-2022 走看看