使用vue-cropper完成头像上传功能

本文展示了如何在Vue3.2.26项目中使用vue-cropperv1.0.9组件实现用户头像的上传和裁剪功能,包括完整代码示例和相关的API调用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue版本 v3.2.26;vue-cropper版本 v1.0.9

功能展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

完整代码

<template>
  <div>
    <div
      class="avatar"
      style="margin-left: 40px; position: relative; width: 137px; height: 137px"
    >
      <img
        v-if="cropperOption.imageUrl"
        style="width: 100%; height: 100%; border-radius: 50%; object-fit: cover"
        :src="cropperOption.imageUrl"
        alt=""
      />

      <el-avatar v-else :size="137" style="">
        <el-icon size="72"> <UserFilled /> </el-icon>
      </el-avatar>
      <div class="avatar_camera" @click="uploadAvatar()">
        <el-icon size="25"><CameraFilled /></el-icon>
      </div>
    </div>
    <MyDialog title="头像上传" top="5%" ref="myDialogRef" width="800">
      <template #content>
        <div style="width: 760px; height: 450px; display: flex">
          <vueCropper
            ref="cropperRef"
            :img="cropperOption.img"
            :output-size="cropperOption.size"
            :output-type="cropperOption.outputType"
            :info="true"
            :full="cropperOption.full"
            :can-move="cropperOption.canMove"
            :can-move-box="cropperOption.canMoveBox"
            :fixed-box="cropperOption.fixedBox"
            :original="cropperOption.original"
            :auto-crop="cropperOption.autoCrop"
            :auto-crop-width="cropperOption.autoCropWidth"
            :auto-crop-height="cropperOption.autoCropHeight"
            :center-box="cropperOption.centerBox"
            :high="cropperOption.high"
            mode="contain"
            :max-img-size="cropperOption.max"
          ></vueCropper>
        </div>

        <div style="margin-top: 20px; text-align: center">
          <el-button
            style="
              width: 84px;
              height: 32px;
              color: #1a1a1a;
              background: #f2f3f5;
            "
            :icon="Close"
            @click="myDialogRef.hideDialog()"
            >取 消</el-button
          >
          <el-button
            style="width: 84px; height: 32px; color: #fff; background: #0256ff"
            :icon="Position"
            @click="handleCrapFinished"
            >确认</el-button
          >
        </div>
      </template>
    </MyDialog>
  </div>
</template>

<script setup>
// 头像上传
import 'vue-cropper/dist/index.css'
import { VueCropper } from 'vue-cropper'
import { UserFilled } from '@element-plus/icons-vue'
import { ref, getCurrentInstance, nextTick } from 'vue'
import { Close, Position } from '@element-plus/icons-vue'
import { uploadFile } from '@/api/common.js'
import { baseUrl } from '@/config/env'
const { proxy } = getCurrentInstance()
const cropperRef = ref('')
// const crap = ref(false)
const myDialogRef = ref('')
const cropperOption = ref({
  img: '',
  size: 1,
  full: false,
  outputType: 'png',
  canMove: true,
  fixedBox: false,
  original: false,
  canMoveBox: true,
  autoCrop: true,
  // 只有自动截图开启 宽度高度才生效
  // autoCropWidth: 750,
  // autoCropHeight: 340,
  centerBox: true,
  high: true,
  max: 99999,
  fileinfo: [],
  imageUrl: '',
  // imageUrl: new URL('../..//img/img1.jpg', import.meta.url).href, //裁剪后的url
})

let avatarObj = {}
// 上传头像
const uploadAvatar = () => {
  proxy.$fileTypeLimit
    .upload(true, '', '.gif,.jpeg,.png,.jpg,.svg,')
    .then(file => {
      // console.log('file', file)
      cropperOption.value.img = getObjectURL(file[0])
      // console.log('getObjectURL(file[0])', getObjectURL(file[0]), file[0])
      cropperOption.value.fileinfo = file[0]
      myDialogRef.value.showDialog()
      nextTick(() => {
        // console.log(34343434, cropperRef.value)
        cropperRef.value.startCrop()
      })
    })
}

const handleCrapFinished = () => {
  cropperRef.value.getCropBlob(data => {
    // do something
    let file = new File([data], cropperOption.value.fileinfo.name, {
      type: cropperOption.value.fileinfo.type,
      lastModified: Date.now(),
    })
    let formData = new FormData()
    formData.append('file', file)
    // 上传头像的接口
    uploadFile(formData).then(res => {
      avatarObj = {
        ...res.data.data,
      }
      cropperOption.value.imageUrl = baseUrl + res.data.data.url
      // crap.value = false
      myDialogRef.value.hideDialog()
    })
  })
}

const getObjectURL = f => {
  if (!f) return
  let url = null
  if (window.createObjectURL != undefined) {
    // basic
    url = window.createObjectURL(f)
  } else if (window.URL != undefined) {
    // mozilla(firefox)
    url = window.URL.createObjectURL(f)
  } else if (window.webkitURL != undefined) {
    // webkit or chrome
    url = window.webkitURL.createObjectURL(f)
  }
  return url
}

const getAvatarObj = () => {
  return avatarObj
}

const setImageUrl = (assignmentFile = {}) => {
  if (!assignmentFile.url) return
  cropperOption.value.imageUrl = `${baseUrl}${assignmentFile.url}`
  avatarObj = {
    ...assignmentFile,
  }
}
defineExpose({
  getAvatarObj,
  setImageUrl,
})
</script>
<style lang="scss" scoped>
.avatar_camera {
  cursor: pointer;
  position: absolute;
  width: 48px;
  height: 48px;
  border: 2px solid #fff;
  background: #e8f3ff;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
  right: -5px;
  bottom: -5px;
}
:deep(.el-avatar) {
  overflow: visible;
}
</style>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值