vue3中使用cropperjs、vuedraggable封装裁剪和拖拽图片

裁剪图片首先安装所用到的插件

这次所用需求是将vue2代码改为vue3 其中所用到的组件是裁剪和拖拽

"vuedraggable": "^4.1.0",     "cropperjs": "^1.6.1", 这是所安装的依赖版本

npm i cropperjs
<simpleCropper :initParam="options"
                               :successCallback="uploadHandle"
                               ref="cropp"
                               class="box">
                  <img class="cimg"
                       :src="ossurl + form.wxewmurl"
                       @click="upload('cropp')"
                       v-if="form.wxewmurl" />
                  <img class="cimg"
                       src="@/assets/abt/img/ewm1.png"
                       @click="upload('cropp')"
                        />
                </simpleCropper>
const options = ref({
  img: '',
  file: "mpqrcode",
  type: "mpqrcode",
  fileType: "recruit", // 其他上传参数
  uploadURL: "/empno/getUpload", // 上传地址
  scale: 4, // 相对手机屏幕放大的倍数: 4倍
  ratio: 1 / 1,
  outputsize: 1,//裁剪生成图片的质量
  outputType: 'jpeg',// 裁剪生成图片的格式 jpeg,png,webpoutputType:
  info: false,//裁剪框的大小信息
  canScale: false,// 图片是否允许滚轮缩放
  autoCrop: true,// 是否默认生成截图框
  autocropwidth: 300,// 默认生成截图框宽度
  autoCropHeight: 450,// 默认生成截图框高度
  fixedBox: false,//固定截图框大小 不允许改变fixed: false,// 是否开启截图宽高固定比例,这个如果设置为true,截图框会是固定比例缩放的,如果设置为false,则截图框的狂宽fixedNumber: [1,2],// 截图框的宽高比例  宽度 ,高度 ]
  canMove: true,// 上传图片是否可以移动
  canMoveBox: true,// 截图框能否拖动
  original: false,// 上传图片按照原始比例渲染
  centerBox: true,// 截图框是否被限制在图片里面
  infoTrue: true,// true 为展示真实输出图片宽高 false 展示看到的截图框宽高
  ful1: true,// 是否输出原图比例的截图
  enlarge: 1,// 图片根据截图框输出比例倍数
  mode: 'contain', // 图片默认渲染方式 contain,cover, 100px,10% auto
})


// 上传微信二维码成功回调
const uploadHandle = (data) => {
  form.value.wxewmurl = data.path;  //有接口
  updateCard(form.value).then(res => {
    showSuccessToast('上传成功');
  });
}

// 上传微信二维码
const cropp = ref(null)
const upload = () => {
  if (empno.value == user.value.empno) {
    cropp.value.upload();
  }
}

import simpleCropper from "../component/simpleCropper.vue"  引入封装的组件

<template>
  <div class="v-simple-cropper">
      <slot>
          <button @click="upload">上传图片</button>
      </slot>
      <input class="file" ref="file" type="file" accept="image/*" @change="uploadChange" />
      <div class="v-cropper-layer" ref="layer">
          <div class="layer-header">
              <button class="cancel" @click="cancelHandle">取消</button>
              <button class="confirm" @click="confirmHandle">裁剪</button>
          </div>
          <img ref="cropperImg">
      </div>
  </div>
</template>

<script setup>
import Cropper from 'cropperjs'
import 'cropperjs/dist/cropper.min.css'
import { showLoadingToast, closeToast } from 'vant';
import { uploadBase64Img } from '@/api/yqh.js'
import { onMounted, ref, defineProps } from 'vue'
const props = defineProps({
  initParam: {
      default: {},
      type: Object
  },
  successCallback: {
      type: Function,
      default: () => { }
  }
})
let cropper = ref({})
let filename = ref('')
let cropperImg = ref(null)
let file = ref(null)
let layer = ref(null)
// let ratio = ref('')
// 初始化裁剪插件
const init = () => {
  cropper.value = new Cropper(cropperImg.value, {
      aspectRatio: props.initParam['ratio'],
      dragMode: 'move'
  })
}
// 点击上传按钮
const upload = () => {
  file.value.click()
}
// 选择上传图片
const uploadChange = (e) => {
  let file = e.target.files[0]
  filename.name = file['name']
  let URL = window.URL || window.webkitURL
  layer.value.style.display = 'block'
  cropper.value.replace(URL.createObjectURL(file))
}
// 取消上传
const cancelHandle = () => {
  cropper.value.reset()
  layer.value.style.display = 'none'
  file.value.value = ''
}
const confirmHandle = () => {
  showLoadingToast('上传中...')
  let cropBox = cropper.value.getCropBoxData()
  let scale = props.initParam['scale'] || 1
  let cropCanvas = cropper.value.getCroppedCanvas({
      width: cropBox.width * scale,
      height: cropBox.height * scale
  })
  let imgData = cropCanvas.toDataURL('image/jpeg')
  let data = {
      type: props.initParam['type'],
      file: imgData
  }
  layer.value.style.display = 'none'
  uploadBase64Img(data).then(res => {
      props.successCallback(res.data.data)
      cancelHandle()
      closeToast();
  })
}
onMounted(() => {
  init(1 / 1)
})
defineExpose({
  upload
})
</script>

<style scoped lang="less">
.v-simple-cropper {
  touch-action: none;

}

.file {
  display: none
}

.v-cropper-layer {
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background: #fff;
  z-index: 99999;
  display: none;
}

.layer-header {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 99999;
  background: #fff;
  width: 100%;
  height: 1.1rem;
  line-height: 1.1rem;
  padding: 0 .2rem;
  box-sizing: border-box;
}

.cancel,
.confirm {
  line-height: 1.1rem;
  height: 1.1rem;
  font-size: .45rem;
  background: inherit;
  border: 0;
  outline: 0;
  float: left;
}

.confirm {
  float: right;

}

.confirm img {
  position: inherit !important;
  border-radius: inherit !important;
  float: inherit !important;
}
</style>

使用拖拽的时候 

npm i Draggable
<ul class="clearfix">
            <Draggable :animation="300"
                       :list="form.photo"
                       item-key="id"
                       class="boxlist"
                       ghost-class="ghost"
                       draggable=".item"
                       @start="onStartFriLink"
                       @end="onEndFriLink">
              <template #item="{ element,index }">
                <li class="item">
                  <img :src="ossurl + element"
                       class="img"
                       alt=""
                       v-if="element">
                  <div class="del_img"
                       @touchstart="delMyphoto(index)"></div>
                </li>
              </template>
            </Draggable>
            <simpleCropper :initParam="options"
                           v-if="zplen >= 0 && zplen < 9"
                           :successCallback="TX_uploadHandle"
                           ref="TX_cropper"
                           class="box">
              <li v-if="zplen >= 0 && zplen < 9">
                <img class="img"
                     src="@/assets/abt/img/add.png"
                     @click="TX_uploadImg" />
              </li>
            </simpleCropper>
          </ul>
options和上面的配置相同

// 上传头像成功回调
const TX_uploadHandle = (data) => {
  if (form.value.photo.length <= 9) {
    form.value.photo.push(data.path);
    zplen.value = form.value.photo.length
  } else {
    zplen.value = 9
    return
  }
}
// 只允许上传9张图
const TX_cropper = ref(null)
const TX_uploadImg = () => {
  if (form.value.photo.length >= 9) {
    showFailToast('最多上传9张照片');
  } else {
    TX_cropper.value.upload();  //上传
  }
}
// 删除照片
const delMyphoto = (index) => {
  form.value.photo.splice(index, 1);
  zplen.value -= 1;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值