#博学谷IT学习技术支持#
目录
vue图片上传总结
1.file类型的input绑定事件
2.change事件
3.弹出层展开
4.在弹出层组件中
1.file类型的input绑定事件
<input
type="file"
hidden
ref="file"
@change="onFileChange"
>
2.change事件
import UpdatePhoto from './components/update-photo'
export default {
components: {
UpdatePhoto
},
data () {
return {
img: null // 预览的图片
}
},
methods: {
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 = ''
} } }
3.弹出层展开
在index中
<!-- 编辑头像 -->
<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>
<!-- /编辑头像 -->
4.在弹出层组件中
<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>
import 'cropperjs/dist/cropper.css'
import Cropper from 'cropperjs'
import { updateUserPhoto } from '@/api/user'
export default {
name: 'UpdatePhoto',
components: {},
props: {
img: {
type: [String, Object],
required: true
}
},
data () {
return {
cropper: null
}
},
computed: {},
watch: {},
created () {},
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.updateUserPhoto(blob)
})
},
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('更新失败')
}
}
}
}
</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>
图片裁切功能用到了Cropper插件