This tutorial is out of date and no longer maintained.
Warning: Since publication, this component has the notice: “This component has far outgrown my initial expectations and I’m not able to provide the amount of support that users require.”
vue-dropzone
is a Vue component implemented on top of Dropzone.js that provides drag and drop functionality for file uploads with image previews.
It’s quite powerful and has many options, although it gives you a great deal of functionality out-of-the-box with almost no configuration. You can do multiple file uploads, cancel them, validate file size and format, show a progress bar, and much more!
Let’s start by installing vue-dropzone
:
- npm install vue2-dropzone
Then, in our main.js
entry point file we need to import the CSS file:
import 'vue2-dropzone/dist/vue2Dropzone.css'
In order to create a basic image upload, you need to import the component, and use it providing an id
an options
properties:
<template>
<div id="app">
<vue-dropzone id="drop1" :options="dropOptions"></vue-dropzone>
</div>
</template>
<script>
import vueDropzone from "vue2-dropzone";
export default {
data: () => ({
dropOptions: {
url: "https://httpbin.org/post"
}
}),
components: {
vueDropzone
}
};
</script>
Note: The URL https://httpbin.org/post
is an endpoint from an HTTP service that returns a valid response for any HTTP POST call.
The only required option is url
but there are many more you can use.
For example, let’s say you want:
You could apply all those business rules to the component as follows:
export default {
data: () => ({
dropOptions: {
url: "https://httpbin.org/post",
maxFilesize: 2, // MB
maxFiles: 4,
chunking: true,
chunkSize: 500, // bytes
thumbnailWidth: 150, // px
thumbnailHeight: 150,
addRemoveLinks: true
}
})
// ...
}
The addRemoveLinks
option adds a cancel and remove link to each preview of the dropzone.
You can check the full options in the dropzone docs.
If we want to implement custom functionality, vue-dropzone
exposes several methods that we can access by using a ref
on the <vue-dropzone>
tag.
For example, we can implement a button that removes all the uploaded files:
<template>
<div id="app">
<vue-dropzone ref="dropzone" id="drop1" :options="dropOptions"></vue-dropzone>
<button @click="removeAllFiles">Remove All Files</button>
</div>
</template>
<script>
import vueDropzone from "vue2-dropzone";
export default {
// ...
methods: {
removeAllFiles() {
this.$refs.dropzone.removeAllFiles();
}
}
};
</script>
There are a bunch of events you can use to perform any kind of action when something happens.
For example, to check when a file has been uploaded we can use the vdropzone-complete
event:
<template>
<div id="app">
<vue-dropzone
ref="dropzone"
id="drop1"
:options="dropOptions"
@vdropzone-complete="afterComplete"
></vue-dropzone>
<button @click="removeAllFiles">Remove All Files</button>
</div>
</template>
<script>
import vueDropzone from "vue2-dropzone";
export default {
// ...
methods: {
afterComplete(file) {
console.log(file);
}
}
};
</script>
You won’t need to use events for many of the common operations, not even for showing a message when an upload fails, or when an upload is canceled. vue-dropzone
gives you all that by default in a customizable form, so before using an event check if that functionality you want is already there.
In order to customize the style of the dropzone, first you must set the include-styling
property to false
to turn off the default styling:
<vue-dropzone
id="drop1"
:include-styling="false"
></vue-dropzone>
Then provide a previewTemplate
options, passing a string with the template and the right structure which is defined by its classes. As a starting point, we can take the template example from the official example:
<vue-dropzone
id="drop1"
:options="dropOptions"
:include-styling="false"
></vue-dropzone>
<script>
const getTemplate = () => `
<div class="dz-preview dz-file-preview">
<div class="dz-image">
<div data-dz-thumbnail-bg></div>
</div>
<div class="dz-details">
<div class="dz-size"><span data-dz-size></span></div>
<div class="dz-filename"><span data-dz-name></span></div>
</div>
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
<div class="dz-error-message"><span data-dz-errormessage></span></div>
<div class="dz-success-mark"><i class="fa fa-check"></i></div>
<div class="dz-error-mark"><i class="fa fa-close"></i></div>
</div>
`;
export default {
data: () => ({
dropOptions: {
previewTemplate: getTemplate()
}
})
}
</script>
Then it’ll be possible to style it using CSS by targeting the different class names:
<style>
#drop1 {
height: 200px;
padding: 40px;
color: white;
background: black;
}
#drop1 .dz-preview {
width: 160px;
}
/* ... */
</style>
I hope this introduction has given you a starting point to go and play with vue-dropzone
yourself.
You can find a working demo and the code from this article in this Codesandbox.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.