一、修改头像——实现图片预览功能
// 增加一个文件选择标签,让头像行点击触发文件选择器的点击事件,在src/views/user-profile/index.vue中
<input type="file" hidden ref="file" @change="onFileChange" >
<!-- 个人信息 -->
<van-cell
class="photo-cell"
title="头像"
is-link
center
@click="$refs.file.click()"
>
<van-image
class="avatar"
fit="cover"
round
:src="user.photo"/>
</van-cell>
methods: {
onFileChange () {
// 获取文件对象
const file = this.$refs.file.files[0]
// 基于文章对象获取 blob 数据
const data = window.URL.createObjectURL(file)
console.log(data)
}
}
二、修改头像——功能处理
// 准备弹出层
<!-- 编辑头像 -->
<van-popup
v-model="isUpdatePhotoShow"
position="bottom"
style="height: 100%;"
>
编辑头像编辑头像编辑头像
</van-popup>
<!-- /编辑头像 -->
//定义存储头像预览数据变量和弹框控制变量
data () {
return{
......
isUpdatePhotoShow: false,
img: null // 预览的图片
}
},
// 赋值预览图片地址数据
onFileChange () {
// 获取文件对象
const file = this.$refs.file.files[0]
// 基于文章对象获取 blob 数据
this.img = window.URL.createObjectURL(file)
// 展示预览图片弹出层
this.isUpdatePhotoShow = true
// file-input 如果选了同一个文件不会触发 change 事件
// 解决办法就是每次使用完毕,把它的 value 清空
this.$refs.file.value = ''
}
三、 修改头像——子组件
// 创建update-photo.vue组件
<template>
<div class="update-photo">
<img class="img" :src="img" ref="img">
<div class="toolbar">
<div class="cancel" @click="$emit('close')">取消</div>
<div class="confirm" @click="onConfirm">完成</div>
</div>
</div>
</template>
<script>
export default {
name: 'UpdatePhoto',
components: {},
props: {
// 预览图片地址信息
img: {
type: [String, Object],
required: true
}
},
data () {
return {}
},
computed: {},
watch: {},
created () {},
mounted () {},
methods: {
// 确定事件
onConfirm(){
}
}
}
</script>
<style scoped lang="less">
.update-photo {
background-color: #000;
height: 100%;
.toolbar {
position: fixed;
left: 0;
right: 0;
bottom: 0;
display: flex;
justify-content: space-between;
.cancel, .confirm {
width: 90px;
height: 90px;
font-size: 30px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
}
}
}
.img {
display: block;
max-width: 100%;
}
</style>
//父组件 user-profile/index.vue 导入,注册,使用 且监听关闭事件
import UpdatePhoto from './components/update-photo'
components: {
.....
UpdatePhoto
},
<!-- 编辑头像 -->
<van-popup
v-model="isUpdatePhotoShow"
position="bottom"
style="height: 100%;"
>
<update-photo
v-if="isUpdatePhotoShow"
:img="img"
@close="isUpdatePhotoShow = false"
/>
</van-popup>
<!-- /编辑头像 -->
四、修改头像——实现图片裁剪上传
// 安装cropperjs
yarn add cropperjs 或者 npm i cropperjs
// 在子组件中导入使用,初始化
import 'cropperjs/dist/cropper.css'
import Cropper from 'cropperjs'
data () {
return {
cropper: null // 裁剪器对象
}
}
mounted () {
const image = this.$refs.img
this.cropper = new Cropper(image, {
viewMode: 1,
dragMode: 'move',
aspectRatio: 1,
// autoCropArea: 1,
cropBoxMovable: false,
cropBoxResizable: false,
background: false
})
// 不能在这里调用 this.cropper.getCroppedCanvas() 方法!因为裁剪器还没初始化好!
}
// 获取裁剪结果信息
onConfirm () {
// 基于服务端的裁切使用 getData 方法获取裁切参数
// console.log(this.cropper.getData())
// 纯客户端的裁切使用 getCroppedCanvas 获取裁切的文件对象
this.cropper.getCroppedCanvas().toBlob(blob => {
console.log(blob) // 裁剪后的结果信息
})
},
//在api/user.js中封装头像修改方法
export const updateUserPhoto = data => {
return request({
method: 'PATCH',
url: '/v1_0/user/photo',
data
})
}
//页面中导入使用,提交头像资料
import { updateUserPhoto } from '@/api/user'
async updateUserPhoto (blob) {
this.$toast.loading({
message: '保存中...',
forbidClick: true, // 禁止背景点击
duration: 0 // 持续展示
})
try {
// 错误的用法
// 如果接口要求 Content-Type 是 application/json
// 则传递普通 JavaScript 对象
// updateUserPhoto({
// photo: blob
// })
// 如果接口要求 Content-Type 是 multipart/form-data
// 则你必须传递 FormData 对象
const formData = new FormData()
formData.append('photo', blob)
const { data } = await updateUserPhoto(formData)
// 关闭弹出层
this.$emit('close')
// 更新视图
this.$emit('update-photo', data.data.photo)
// 提示成功
this.$toast.success('更新成功')
} catch (err) {
this.$toast.fail('更新失败')
}
}
onConfirm () {
// 基于服务端的裁切使用 getData 方法获取裁切参数
// console.log(this.cropper.getData())
// 纯客户端的裁切使用 getCroppedCanvas 获取裁切的文件对象
this.cropper.getCroppedCanvas().toBlob(blob => {
this.updateUserPhoto(blob)
})
}
//父组件里面监听头像更新事件,修改头像信息
<!-- 编辑头像 -->
<van-popup
v-model="isUpdatePhotoShow"
position="bottom"
style="height: 100%;"
>
<update-photo
v-if="isUpdatePhotoShow"
:img="img"
@close="isUpdatePhotoShow = false"
@update-photo="user.photo = $event"
/>
</van-popup>
<!-- /编辑头像 -->