Vue移动端系列 => [10] 编辑用户头像

修改头像

图片上传预览

1、准备file类型输入框,并通过点击头像触发上传

<input type="file" hidden ref="inputFile">
    <!-- 导航栏 -->
    <van-nav-bar
    class="page-nav-bar"
    title="个人信息"
    left-arrow @click-left="$router.back()" />
    <!-- /导航栏 -->
    <van-cell title="头像" is-link @click="$refs.inputFile.click()">
      <van-image
        class="avatar"
        fit="cover"
        round
        :src="user.photo"
      />
    </van-cell>

2、给input定义change事件

3、获取上传文件信息

inputChange () {
      // 获取文件对象
      const file = this.$refs.inputFile.files[0]
      // 获取blob数据
      const imgUrl = window.URL.createObjectURL(file)
      console.log(imgUrl)
    }

图片上传预览功能处理

1、定义显示弹层

<!-- 编辑头像弹层 -->
    <van-popup
    v-model="isShowUpdateAvatar"
    style="height: 100%"
    position="bottom">
      hello
    </van-popup>
    <!-- 编辑头像弹层 -->
inputChange () {
    // 获取上传文件
    const file = this.$refs.inputFile.files[0]
    const data = window.URL.createObjectURL(file)
    console.log(data)
    this.isShowUpdateAvatar = true
}

2、定义更新图片组件

3、引用、注册、使用

import updateAvatar from './components/update-avatar.vue'
components: {
    updateName,
    updateGender,
    updateBirthdy,
    updateAvatar
}
<!-- 编辑头像弹层 -->
    <van-popup
    v-model="isShowUpdateAvatar"
    style="height: 100%"
    position="bottom">
      <update-avatar : />
    </van-popup>
    <!-- 编辑头像弹层 -->

4、将图片保存到data中并传递给update-avatar组件

inputChange () {
    // 获取上传文件
    const file = this.$refs.inputFile.files[0]
    this.img = window.URL.createObjectURL(file)
    this.isShowUpdateAvatar = true
    this.$refs.inputFile.value = ''
}
<!-- 编辑头像弹层 -->
    <van-popup
    v-model="isShowUpdateAvatar"
    style="height: 100%"
    position="bottom">
      <update-avatar :img="img" />
    </van-popup>
    <!-- 编辑头像弹层 -->

5、update-avatar组件接收并使用

<template>
    <div>
      <img :src="img" />
    </div>
</template>

<script>
export default {
  props: {
    img: {
      type: [String, Object],
      retuired: true
    }
  }
}
</script>

<style scoped lang='less'>

</style>

图片上传预览样式处理

1、结构

<div class="update-avatar">
    <img :src="img" />
    <div class="toolbar">
      <span>取消</span>
      <span>完成</span>
    </div>
  </div>

2、css

.update-avatar {
  background: #000;
  width: 100%;
  height: 100%;
  .toolbar {
    position: fixed;
    bottom: 10px;
    width: 100%;
    display: flex;
    justify-content: space-between;
    font-size: 28px;
    color: #fff;
    padding: 0 15px;
    box-sizing: border-box;
  }
}

3、点击取消

<span @click="$emit('close')">取消</span>
<!-- 编辑头像弹层 -->
<van-popup
           v-model="isShowUpdateAvatar"
           style="height: 100%"
           position="bottom">
    <update-avatar @close="isShowUpdateAvatar = false" :img="img" />
</van-popup>
<!-- 编辑头像弹层 -->

头像裁切

方式一:结合服务器的图片上传预览

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A4NmRZqJ-1605272238940)(F:/课程/课程项目/vue/vue-mobile/vue移动端笔记/assets/1567067894388.png)]

方式二:纯客户端实现上传图片预览

方案一:结合服务端的图片裁切上传流程

方案二:纯客户端的图片裁切上传流程

viewMode: 1,
dragMode: 'move',
aspectRatio: 1,
autoCropArea: 1,
cropBoxMovable: false,
cropBoxResizable: false,
background: false,
movable: true
使用cropperjs

1、安装cropperjs

npm install cropperjs

2、引入css、js

import 'cropperjs/dist/cropper.css'
import Cropper from 'cropperjs'

3、在mounted中初始化

const image = this.$refs.img
const cropper = new Cropper(image, {
    aspectRatio: 16 / 9,
    crop (event) {
        console.log(event.detail.x)
        console.log(event.detail.y)
        console.log(event.detail.width)
        console.log(event.detail.height)
        console.log(event.detail.rotate)
        console.log(event.detail.scaleX)
        console.log(event.detail.scaleY)
    }
})
console.log(cropper)
配置cropperjs
const cropper = new Cropper(image, {
    viewMode: 1, // 只能在裁剪的图片范围内移动
    dragMode: 'move', // 画布和图片都可以移动
    aspectRatio: 1, // 裁剪区默认正方形
    autoCropArea: 1, // 自动调整裁剪图片
    cropBoxMovable: false, // 禁止裁剪区移动
    cropBoxResizable: false, // 禁止裁剪区缩放
    background: false // 关闭默认背景
})
裁切的两种方式- 服务端

获取参数

1、获取cropper实例

this.cropper = new Cropper(image, {
      viewMode: 1, // 只能在裁剪的图片范围内移动
      dragMode: 'move', // 画布和图片都可以移动
      aspectRatio: 1, // 裁剪区默认正方形
      autoCropArea: 1, // 自动调整裁剪图片
      cropBoxMovable: false, // 禁止裁剪区移动
      cropBoxResizable: false, // 禁止裁剪区缩放
      background: false // 关闭默认背景
    })

2、给确定注册点击事件,在事件函数中获取参数

<span @click="confirm">完成</span>
confirm () {
    console.log(this.cropper.getData())
}
客户端方式
confirm () {
      // console.log(this.cropper.getData())
      this.cropper.getCroppedCanvas().toBlob(blob => {
        console.log(blob)
      })
    }

实现裁剪图片提交

1、封装更新头像api

/**
 * 更新头像
 */
export const updateUserAvatar = data => {
  return request({
    method: 'PATCH',
    url: '/app/v1_0/user/photo',
    data
  })
}

2、引入方法并调用

import { updateUserAvatar } from '@/api/user.js'
confirm () {
      this.cropper.getCroppedCanvas().toBlob(async blob => {
        // 创建formData数据
        const formData = new FormData()
        formData.append('photo', blob)
        const res = await updateUserAvatar(formData)
        console.log(res)
      })
    }

3、关闭弹层、更新视图

this.cropper.getCroppedCanvas().toBlob(async blob => {
        const formData = new FormData()
        formData.append('photo', blob)
        const { data } = await updateUserAvatar(formData)
        // 关闭弹层,更新视图
        this.$emit('close')
        this.$emit('update-avatar', data.data.photo)
      })
<update-avatar
      @update-avatar="user.photo = $event"
      @close="isShowUpdateAvatar = false"
      :img="img" />

4、利用v-if重置数据

<update-avatar
      v-if="isShowUpdateAvatar"
      @update-avatar="user.photo = $event"
      @close="isShowUpdateAvatar = false"
      :img="img" />

5、优化loading效果

async updateAvatar (blob) {
      this.$toast.loading({
        message: '保存中...',
        forbidClick: true,
        loadingType: 'spinner',
        duration: 0
      })
      try {
        const formData = new FormData()
        formData.append('photo', blob)
        const { data } = await updateUserAvatar(formData)
        // 关闭弹层,更新视图
        this.$emit('close')
        this.$emit('update-avatar', data.data.photo)
        this.$toast('更新成功')
      } catch (err) {
        this.$toast('更新失败')
      }
    }
### 实现 Vue3 移动端头像截取功能 为了在 Vue3 项目中实现移动端头像截取功能,可以采用 `vue-cropper` 这一插件来简化开发过程。以下是具体方法: #### 安装依赖包 首先,在项目根目录下通过命令行安装所需的依赖包: ```bash npm install vue-cropper@next ``` 接着,需引入样式文件以及组件本身到项目的入口文件或所需使用的单文件组件内: ```javascript import 'vue-cropper/dist/index.css' import { VueCropper } from "vue-cropper"; ``` #### 创建裁剪界面模板结构 构建用于展示和操作图像裁剪区域的基础 HTML 结构。这里以 Vant 组件库为例说明如何创建上传按钮,并设置最大尺寸限制防止过大文件被提交。 ```html <template> <div id="app"> <!-- 更换头像 --> <van-uploader class="mt-3" :max-size="3 * 1024 * 1024" :before-read="beforeRead" @oversize="onOversize" > <van-button icon="manager-o" size="small" type="primary">更换头像</van-button> </van-uploader> <!-- 图片预览区 --> <img v-if="croppedImageUrl" :src="croppedImageUrl" alt="" /> <!-- 裁剪器容器 --> <VueCropper ref="cropper"></VueCropper> </div> </template> ``` #### 编写逻辑处理函数 接下来编写 JavaScript 方法用来控制图片的选择、显示及保存等功能。这些方法将在用户交互事件触发时调用。 ```javascript <script setup lang="ts"> import { ref, onMounted } from 'vue'; // 导入其他必要的模块... const cropper = ref(null); let croppedImageUrl = ref(''); function beforeRead(file){ const reader = new FileReader(); reader.onloadend = function () { // 将读取的结果传递给裁剪器实例初始化源图 cropper.value && (cropper.value.img = this.result as string); }; reader.readAsDataURL(file); return false; } async function cropImage(){ try{ let dataUrl = await cropper.value.getCropData(); croppedImageUrl.value = dataUrl; console.log('Cropped image:',dataUrl); } catch(error){ alert(`Error cropping image:${error.message}`); } } </script> ``` 以上代码片段展示了如何利用 `vue-cropper` 和 Vant UI 库快速搭建起一套完整的移动设备上针对个人资料照片编辑的功能[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

不停喝水

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

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

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

打赏作者

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

抵扣说明:

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

余额充值