<template>
<div class="user-profile">
<input type="file" name="" id="" ref="file" hidden @change="onFileChange" />
<!-- 个人信息 -->
<van-cell title="头像" is-link @click="$refs.file.click()">
<van-image class="avatar" fit="cover" round :src="user.photo" />
</van-cell>
//此为组件
<!-- 修改头像 -->
<van-popup
style="height: 100%"
position="bottom"
v-model="isUpdatePhotoShow"
>
<updatePhoto
:img="img"
@close="isUpdatePhotoShow = false"
v-if="isUpdatePhotoShow"
@updatePhoto="user.photo = $event"
/>
</van-popup>
<!-- 修改头像 -->
</div>
</template>
export default {
data() {
return {
user: {}, //用户的个人资料
isUpdatePhotoShow: false, //头像弹出层
img: null,
};
},
created() {
this.loadProfile();
},
components: {
updatePhoto,
},
methods: {
//调取接口,获取user数据
async loadProfile() {
try {
const { data } = await getProfileList();
this.user = data.data;
} catch (err) {
this.$toast("数据加载失败,请稍后重试");
}
},
onFileChange() {
// 获取文件对象
const file = this.$refs.file.files[0];
// console.log(file);
// 基于文章对象获取blob数据
let binaryData = [];
binaryData.push(file);
const data = window.URL.createObjectURL(
new File(binaryData, { type: "application/pdf;chartset=UTF-8" })
);
this.img = data;
//解决bug,解决选择的头像是同一张,然后不弹出弹层的问题
//把每次选择的默认值清空
this.$refs.file.value = "";
//图片选择好了之后,弹出弹层
this.isUpdatePhotoShow = true;
},
},
};
以下为图片裁剪组件(图片裁剪主要是要使用cropper.js这个插件,然后配置一下)
<template>
<div class="updatePhoto">
<img :src="img" alt="" class="img" ref="img" />
<div class="toolbar">
<div class="cancel" @click="$emit('close')">取消</div>
<div class="confirm" @click="onConfirm">完成</div>
</div>
</div>
</template>
<script>
import "cropperjs/dist/cropper.css";
import Cropper from "cropperjs";
import { updateUserPhoto } from '@/api/login.js'
export default {
props: {
img: {
type: [String, Object],
require: true,
},
},
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,
});
},
methods:{
onConfirm(){
// 基于服务端的裁切使用getData方法获取裁切参数
// console.log(this.cropper.getData())
// 纯客户端的裁切使用getCroppedCanvas获取裁切文件对象
this.cropper.getCroppedCanvas().toBlob(blob => {
this.updatePhoto(blob)
})
},
async updatePhoto(blob){
// 接口要求必须传formData格式
const formData = new FormData()
formData.append('photo',blob)
try{
const { data } = await updateUserPhoto(formData)
this.$emit('close') //关闭弹窗
this.$emit('updatePhoto',data.data.photo)//更新图片
this.$toast.success('更新成功')
}catch(err){
this.$toast.fail('更新失败')
}
}
}
};
</script>
<style scoped lang="less">
.updatePhoto {
height: 100%;
// display: flex;
// justify-content: center;
// align-items: center;
background-color: #000;
.img {
max-width: 100%;
display: block;
}
.toolbar {
// border: 1px solid blue;
position: fixed;
bottom: 0px;
left: 0px;
right: 0px;
display: flex;
justify-content: space-between;
.cancel,
.confirm {
width: 90px;
height: 90px;
font-size: 40px;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
}
}
}
</style>