1.前言
在现代互联网应用中,图片上传和预览功能已经成为必备的功能之一。本文将通过Vue实现图片上传和预览的功能,使得用户可以上传并查看一个或多个图片。实现此功能可以使用Vue插件 Vue-Croppa。Vue-Croppa提供了一个简单的方法使用Vue来上传和裁剪(可选)图片。它基于组件的模式开发,使得我们可以很方便地使用并自定义它。
2.安装
使用npm安装Vue-Croppa,可以使用以下命令安装:
npm install vue-croppa --save
接下来,在main.js文件中,我们需要将其导入我们的Vue实例。
import VueCroppa from 'vue-croppa'
import 'vue-croppa/dist/vue-croppa.css'
Vue.use(VueCroppa)
3.组件创建
我们需要创建一个组件来实现图片上传和预览的功能。Vue-Croppa提供了提供croppa组件来处理上传和裁剪。我们可以像下面一样在组件中使用Cropper:
<template>
<div>
<Cropper ref="cropper" :width="200" :height="200" :placeholder="'Upload your picture'" v-model="myAvatar"></Cropper>
</div>
</template>
在这个组件中,cropper可以使用ref标识元素。我们还可以设置其宽度和高度,并为其提供占位符。
4.图片上传
4.1 图片上传功能实现
通过Vue-Croppa实现的 图片上传 功能会自动捕获所选文件的“change”事件(当我们选择了文件时)。上传时,请调用cropper的upload()方法。此方法将返回一个Promise,其中resolve()会在文件上传成功后调用,reject()则会在文件上传失败时调用。
添加按钮,来触发图片上传功能:
<template>
<div>
<Cropper ref="cropper" :width="300" :height="300" v-model="myAvatar"></Cropper>
<div>
<button @click="submitAvatar()">Submit</button>
<input ref="fileInput" type="file" accept="image/*" style="display:none;" @change="selectFile">
</div>
</div>
</template>
在这里我们使用了一个input标签,并将其隐藏,然后通过控制代码触发它的点击事件。
<script>
export default {
name: 'App',
data: () => ({
myAvatar: null
}),
methods: {
submitAvatar () {
this.$refs.cropper.upload()
.then(() => {
console.log('Upload successful')
})
.catch(() => {
console.log('Upload failed')
})
},
selectFile () {
this.$refs.cropper.image = this.$refs.fileInput.files[0]
}
}
}
</script>
4.2 图片上传功能添加进度条
我们可以添加一个进度条,让用户更直观地看到上传的进度。
在本质上,我们可以使用XMLHttpRequest对象来向服务器发送请求。查看文件上传进度,我们还可以使用XMLHttpRequestUpload对象。实际上,XMLHttpRequestUpload对象公开了一些事件,用于跟踪上传的进度和状态。
我们将使用XMLHttpRequestUpload中的progress事件,该事件在上传期间接收文件上传进度的更新。实现代码如下:
<template>
<div>
<Cropper ref="cropper" :width="300" :height="300" v-model="myAvatar"></Cropper>
<div>
<button @click="submitAvatar()">Submit</button>
<input ref="fileInput" type="file" accept="image/*" style="display:none;" @change="selectFile">
<div v-if="progress">
<progress :max="fileSize" :value="progress"></progress>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'App',
data: () => ({
myAvatar: null,
progress: 0,
fileSize: null
}),
methods: {
submitAvatar () {
if (this.myAvatar) {
this.fileSize = this.myAvatar.size
this.$refs.cropper.upload()
.then(() => {
console.log('Upload successful')
})
.catch(() => {
console.log('Upload failed')
})
}
},
selectFile () {
this.$refs.cropper.image = this.$refs.fileInput.files[0]
}
},
mounted () {
const xhr = new XMLHttpRequest()
xhr.upload.addEventListener('progress', (event) => {
const percent = event.loaded / this.fileSize * 100
this.progress = Math.round(percent)
})
}
}
</script>
在mounted钩子中,我们创建了XMLHttpRequest对象,并使用其upload属性添加EventListener进行监听。我们在`event.loaded / this.fileSize * 100`计算上传进度,并将计算结果设置为数据模型progress的值,以显示在页面上的进度条上。
5.图片预览
我们添加一个方法,在cropper.upload() resolved时调用,来显示所上传文件的缩略图。
<template>
<div>
<Cropper ref="cropper" :width="300" :height="300" v-model="myAvatar" @upload-success="handleSuccess"></Cropper>
<div>
<button @click="submitAvatar()">Submit</button>
<input ref="fileInput" type="file" accept="image/*" style="display:none;" @change="selectFile">
<div v-if="progress">
<progress :max="fileSize" :value="progress"></progress>
</div>
<div v-if="preview">
<img :src="preview" alt="Avatar" style="max-height:300px">
</div>
</div>
</div>
</template>
<script>
export default {
name: 'App',
data: () => ({
myAvatar: null,
progress: 0,
fileSize: null,
preview: null
}),
methods: {
submitAvatar () {
if (this.myAvatar) {
this.fileSize = this.myAvatar.size
this.$refs.cropper.upload()
.then(() => {
console.log('Upload successful')
})
.catch(() => {
console.log('Upload failed')
})
}
},
selectFile () {
this.$refs.cropper.image = this.$refs.fileInput.files[0]
},
handleSuccess (newValue) {
if (newValue) {
this.preview = URL.createObjectURL(newValue)
}
}
},
mounted () {
const xhr = new XMLHttpRequest()
xhr.upload.addEventListener('progress', (event) => {
const percent = event.loaded / this.fileSize * 100
this.progress = Math.round(percent)
})
}
}
</script>
我们添加了一个新的数据模型preview来保存新图像。然后,在Cropper组件上添加一个名为handleSuccess方法,在myAvatar数据模型更新时触发它。在这里,我们使用URL.createObjectURL方法生成模型的缩略图URL。
6.总结
本文详细介绍了如何使用Vue-Croppa和Vue来实现图片上传和预览功能。我们使用Vue-Croppa组件,实现了文件上传的功能,并将progress事件监听绑定到在mounted钩子中创建的XMLHttpRequest对象上,来显示上传的进度。最后,我们使用URL.createObjectURL方法来生成上传图片的缩略图URL,获取图片预览效果。