修改头像
图片上传预览
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('更新失败')
}
}