vue3图片头像裁剪上传

本文介绍如何在Vue3项目中实现图片的裁剪和上传功能,通过使用vue-cropper组件,详细讲解了从安装到配置的全过程,包括组件引用、HTML结构、CSS样式以及JavaScript处理逻辑。

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

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

1.安装vue-cropper

pnpm add vue-cropper@next

2.组件内引用

import 'vue-cropper/dist/index.css'//引入圖片裁剪
import { VueCropper }  from "vue-cropper";

3.html部分

<van-popup v-model:show="showCropper" overlay-class="dialog" @click-overlay="delCropper">
    <div class="button-group">
      <van-button type="success" size="mini" @click="getCropBlob">Confirm</van-button>
      <van-button type="danger" size="mini" @click="delCropper">Cancel</van-button>
    </div>
      <VueCropper
          ref="cropper"
          :img="option.img"
          :outputSize="option.outputSize"
          :outputType="option.outputType"
          :info="option.info"
          :full="option.full"
          :autoCropWidth="option.autoCropWidth"
          :autoCropHeight="option.autoCropHeight"
          :canMove="option.canMove"
          :canMoveBox="option.canMoveBox"
          :original="option.original"
          :autoCrop="option.autoCrop"
          :fixed="option.fixed"
          :fixedNumber="option.fixedNumber"
          :centerBox="option.centerBox"
          :infoTrue="option.infoTrue"
          :fixedBox="option.fixedBox"
          :high="option.high"
          :mode="option.mode"
      >

      </VueCropper>
  </van-popup>

4.css部分

<style lang="scss" scoped>
:deep(.van-popup) {
  width: 80%;
  height: 80%;
  overflow: hidden;
}
.button-group {
  display: flex;
  justify-content: space-between;
  button {
    margin: 10px;
  }
}
</style>

5.js部分


const first_name = ref()
const last_name = ref()
const phone = ref()
const email = ref()
const wechat = ref()
const line_id = ref()
const fileList = ref([])
const cropper = ref(null)//截取的dom元素
const file = ref()
const option = ref({//裁剪參數
  img: null,
  outputSize: 1,
  info: false, // 裁剪框的大小信息
  outputType: 'jpeg', // 裁剪生成图片的格式
  canScale: false, // 图片是否允许滚轮缩放
  autoCrop: true, // 是否默认生成截图框
  autoCropWidth:  '100px', // 默认生成截图框宽度
  autoCropHeight: '100px', // 默认生成截图框高度
  high: true, // 是否按照设备的dpr 输出等比例图片
  fixedBox: false, // 固定截图框大小 不允许改变
  fixed: true, // 是否开启截图框宽高固定比例
  fixedNumber: [1, 1], // 截图框的宽高比例
  full: true, // 是否输出原图比例的截图
  canMoveBox: true, // 截图框能否拖动
  original: false, // 上传图片按照原始比例渲染
  centerBox: true, // 截图框是否被限制在图片里面
  infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
  mode: '100% auto' // 图片默认渲染方式
})
const showCropper = ref(false)

const router = useRouter()

/**
 * 選取圖片後
 * @param file
 * @returns {boolean}
 */
function beforeRead(file) {
  option.value.img = URL.createObjectURL(file)
  showCropper.value = true
  return true
}

/**
 * 取消截圖
 */
function delCropper() {
  fileList.value = []
  showCropper.value = false
}

/**
 * 確認截圖
 */
function getCropBlob() {
  cropper.value.getCropData(e => {
    file.value = e
    showCropper.value = false
  })
}


/**
 * 修改個人信息
 * @type {(function(): void)|*}
 */
const onSubmit = useThrottleFn(() => {
  if(fileList.value.length === 0) {
    let form = {
      first_name: first_name.value,
      last_name: last_name.value,
      phone: phone.value,
      email: email.value,
      wechat: wechat.value,
      line_id: line_id.value
    }
    updateMeApi(form).then(res => {
      if(res.status === 201 ||  res.status === 200) {
        Toast.success('Success');
        setTimeout(() => {
          router.push('/me')
        },2000)
      }
    })
  }else {
    let form = {
      image: file.value,
      first_name: first_name.value,
      last_name: last_name.value,
      phone: phone.value,
      email: email.value,
      wechat: wechat.value,
      line_id: line_id.value
    }
    updateMeApi(form).then(res => {
      if(res.status === 201 ||  res.status === 200) {
        Toast.success('Success');
        setTimeout(() => {
          router.push('/me')
        },2000)
      }
    })
  }
},1000)

6.表单部分仅供参考

 <van-form @submit="onSubmit">
    <header>
      <h1>Personal</h1>
      <h4>Edit</h4>
      <van-field name="uploader" class="upload">
        <template #input>
          <van-uploader :max-count="1" multiple v-model="fileList" :before-read="beforeRead"/>
        </template>
      </van-field>
    </header>
      <h3>Information</h3>
      <van-cell-group inset>
        <van-field
            v-model="first_name"
            name=""
            placeholder="First Name"
            :rules="[{ required: true, message: 'Please fill your first name' }]"
        />
      </van-cell-group>
      <van-cell-group inset>
        <van-field
            v-model="last_name"
            name=""
            placeholder="Last Name"
            :rules="[{ required: true, message: 'Please fill your last name' }]"
        />
      </van-cell-group>
      <van-cell-group inset>
        <van-field
            v-model="phone"
            name="手機號"
            type="Number"
            placeholder="Phone Number such as 886xxxx"
            :rules="[{ required: true, message: 'Please fill your phone number' }]"
        />
      </van-cell-group>
      <van-cell-group inset>
        <van-field
            v-model="email"
            type="email"
            name="用户名"
            placeholder="E-mail"
        />
      </van-cell-group>
      <van-cell-group inset>
        <van-field
            v-model="wechat"
            name="用户名"
            placeholder="WeChat ID"
        />
      </van-cell-group>
      <van-cell-group inset>
        <van-field
            v-model="line_id"
            name="用户名"
            placeholder="LINE ID"
        />
      </van-cell-group>
      <div>
        <van-button round block type="success" native-type="submit">
          Save
        </van-button>
      </div>
    </van-form>
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月光下,遗忘黑暗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值