👧 A simple and elegant component to crop and upload avatars.
<button @click="showCropper = true">Select an image</button>
<avatar-cropper
v-model="showCropper"
upload-url="/files/upload"
@uploaded="handleUploaded"
/>
<script>
export default {
data() {
return {
showCropper: false,
}
},
methods: {
handleUploaded({ form, request, response }) {
// update user avatar attribute
},
},
}
</script>
Pintura the modern JavaScript Image Editor is what you're looking for.
Pintura supports setting crop aspect ratios, resizing, rotating, cropping, flipping images, and more.
-
Include the link to AvatarCropper in
<head>
alongside Vue.js, Cropper.js and Mime:<link rel="stylesheet" href="https://unpkg.com/cropperjs@1.5.12/dist/cropper.min.css" /> <script src="https://unpkg.com/cropperjs@1.5.12/dist/cropper.js"></script> <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <script src="https://unpkg.com/vue-avatar-cropper/dist/avatar-cropper.umd.js"></script> <script src="https://wzrd.in/standalone/mime%2flite@latest"></script>
-
Add a trigger button and
<avatar-cropper>
to mount the component:
<button @click="showCropper = true">Select an image</button>
<avatar-cropper
v-model="showCropper"
upload-url="/files/upload"
@uploaded="handleUploaded"
/>
- Create Vue instance and register
AvatarCropper
component:
<script>
Vue.createApp({
el: '#app',
data() {
return {
showCropper: false,
}
},
methods: {
handleUploaded(event) {
console.log('avatar uploaded', event)
},
},
})
.use(AvatarCropper)
.mount('#app')
</script>
-
Install the AvatarCropper package:
npm install vue-avatar-cropper # or yarn add vue-avatar-cropper
-
Register it as you usually would:
import AvatarCropper from 'vue-avatar-cropper' // or const AvatarCropper = require('vue-avatar-cropper') Vue.component('AvatarCropper', AvatarCropper) // or Vue.use(AvatarCropper) // or new Vue({ components: { AvatarCropper }, // ... })
Property Name | Type | Description |
---|---|---|
modelValue |
Boolean | Set to true to show the avatar cropper, this prop is used for v-model . Default: false |
file |
File | File to use instead of prompting the user to upload one |
upload-url |
String | URL to upload the file to |
upload-file-field |
String | FormData field to use for the file. Default: 'file' |
upload-file-name |
String/Function | File name to use for the FormData field. Can be String or Function({ filename, mime, extension }) => String . Default: Automatically determined from the uploaded File 's name property and the extension of the output MIME. |
upload-form-data |
FormData | Additional FormData . Default: new FormData() |
upload-handler |
Function | Handler to replace default upload handler, the argument is cropperJS instance. |
request-options |
Object | Options passed to the init parameter of the Request() constructor. Use this to set the method, headers, etc. Default: { method: 'POST' } |
cropper-options |
Object | Options passed to the cropperJS instance. Default: { |
aspectRatio: 1, |
||
autoCropArea: 1, |
||
viewMode: 1, |
||
movable: false, |
||
zoomable: false |
||
} |
||
output-options |
Object | Options passed to the cropper.getCroppedCanvas() method. Default: {} . Recommended use-case is specifying an output size, for instance: { width: 512, height: 512 } |
output-mime |
String | The resulting avatar image MIME type, if invalid image/png will be used. Default: null |
output-quality |
Number | The resulting avatar image quality [0 - 1]. Default: 0.9 (if the output-mime property is 'image/jpeg' or 'image/webp' ) |
mimes |
String | Allowed image formats. Default: 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon' |
capture |
String | Capture attribute for the file input. Forces mobile users to take a new picture with the back(Use value 'environment' ) or front(Use value 'user' ) camera |
labels |
Object | Label for buttons. Default: { submit: 'Ok', cancel: 'Cancel' } |
inline |
Boolean | If true component will be displayed as inline elemenet. Default: false |
-
update:modelValue
modelValue
prop changed, used forv-model
, parameter:value
boolean.
-
changed user picked a file, parameter is an object containing:
file
object, File object.reader
object, FileReader
-
submit right after a click on the submit button
-
cancel when user decides to cancel the upload
-
uploading before submit upload request, parameter is an object containing:
-
uploaded after request is successful, parameter is an object containing:
-
completed after request has completed, parameter is an object containing:
-
error something went wrong, parameter is an object containing:
message
error message.type
error type, example:'load'
/'upload'
/'user'
.context
context data.
You can listen for these events like this:
<avatar-cropper
v-model="showCropper"
upload-url="/files/upload"
@uploading="handleUploading"
@uploaded="handleUploaded"
@completed="handleCompleted"
@error="handleError"
/>
export default {
//...
methods: {
...
handleUploading({ form, request, response }) {
// show a loader
},
handleUploaded({ form, request, response }) {
// update user avatar attribute
},
handleCompleted({ form, request, response }) {
// close the loader
},
handleError({ message, type, context}) {
if (type === 'upload') {
const { request, response } = context
}
}
},
}
🚀 There is an online demo:
如果你喜欢我的项目并想支持它,点击这里 ❤️
Many thanks to Jetbrains for kindly providing a license for me to work on this and other open-source projects.
MIT