vue-transmit v8.1.4
Vue-Transmit
A Vue.js drag & drop uploader based on Dropzone.js (~22KB, ~6.5KB gzipped).
Many thanks to Matias Meno for
paving the way with the original Dropzone.js!
Check it out for any of your
non-vue projects. 🙌
Features
Vue-Transmit is a fork of Dropzone.js that has been completely rewritten in TypeScript/ES6 for Vue.js. Instead of creating a Vue wrapper component that duplicates and proxies all of the methods and event logic between Dropzone and the component, Vue-Transmit implements them directly from the component. This cuts down on library size and offers a much tighter integration.
Vue-Transmit takes an event-based approach to the upload cycle. Instead of
passing callbacks to the component via an options object, use the template event
binding syntax (<vue-transmit @event="callback" />). All events strictly
conform to kebab-casing, including events proxied off native events (e.g.
dragover => @drag-over). This is for uniformity and so events can be easily
distinguished.
In order to comply with Vue.js reactivity, an object's properties must be
defined up front and be configurable. A special File class has been written
(VTransmitFile) to register file objects from uploads reactively, since the
native File object's properties are read-only. This class also adds useful
information not present in the native File object (dimensions, upload stats,
etc.).
- HTML 5 file uploads
- Emits upload lifecycle events (accepted, sending, progress, success, etc.)
- Image thumbnail previews
- Support for concurrent uploads
- Completely written in Vue.js—no wrapper components
- Scoped slots allow for fully customizable styling
- Written in modern TypeScript/ES6 with modules
* Note: this library uses some built-ins (Array.from) that require a
polyfill. All other ESNext language features (arrow fns, for of, etc.) are
transpiled with babel.

Installation
npm install vue-transmitBuilds
The default build for ESM loaders like webpack is indicated in the module
fields of the package. For most setups, importing the lib would like the
following:
// ESM
import VueTransmit from "vue-transmit";
// Common.js
const VueTransmit = require("vue-transmit");
// Browser
window.VueTransmit;
// Installation
Vue.use(VueTransmit);| Target | Path | Minified |
|---|---|---|
| ESM | vue-transmit/dist/vue-transmit.esm.js | true |
| AMD | vue-transmit/dist/vue-transmit.js | true |
Props: <vue-transmit>
| Property | Type | Default |
|---|---|---|
| tag | String | "div" |
| uploadAreaClasses | Array, Object, String | null |
| uploadAreaAttrs | Object | {} |
| uploadAreaListeners | Object | {} |
| url | String | undefined |
| method | String | "post" |
| withCredentials | Boolean | false |
| timeout | Number | 0 |
| maxConcurrentUploads | Number | 2 |
| uploadMultiple | Boolean | false |
| maxFileSize | Number | 256 (in MiB) |
| paramName | String | "file" |
| createImageThumbnails | Boolean | true |
| maxThumbnailFileSize | Number | 10 |
| thumbnailWidth | Number | 120 |
| thumbnailHeight | Number | 120 |
| fileSizeBase | Number | 1000 |
| maxFiles | Number | null |
| params | Object | default |
| headers | Object | default |
| responseType | String | "" |
| clickable | Boolean | true |
| ignoreHiddenFiles | Boolean | true |
| acceptedFileTypes | Array | default |
| autoProcessQueue | Boolean | true |
| autoQueue | Boolean | true |
| capture | String | null |
| renameFile | Function | identity |
| dictFileTooBig | String | "File is too big ({{ fileSize }}MiB). Max file size: {{ maxFileSize }}MiB." |
| dictInvalidFileType | String | "You can't upload files of this type." |
| dictResponseError | String | "Server responded with {{ statusCode }} code." |
| dictMaxFilesExceeded | String | "You can not upload any more files." |
| accept | Function | default |
| resize | Function | default |
Events
| Event | Arguments | Description |
|---|---|---|
drop | DragEvent | The drop event is fired when an data transfer is dropped on the drop target. |
drag-start | DragEvent | The drag-start event is fired when the user starts dragging an element or text selection. |
drag-end | DragEvent | The drag-end event is fired when a drag operation is being ended (by releasing a mouse button or hitting the escape key). |
drag-enter | DragEvent | The drag-enter event is fired when a dragged element or text selection enters a valid drop target. |
drag-over | DragEvent | The drag-over event is fired when an element or text selection is being dragged over a valid drop target (every few hundred milliseconds). |
drag-leave | DragEvent | The drag-leave event is fired when a dragged element or text selection leaves a valid drop target. |
added-file | VTransmitFile | Fired on change from the hidden file input after the Native File has been copied to VTransmitFile and added to the component data. (status: 'added') |
added-files | VTransmitFile[] | Fired on change from the hidden file input after the Native Files have been copied to VTransmitFiles and added to the component data. (status: 'added') |
accepted-file | VTransmitFile | Fired if the user-supplied accept function returns without error. (status: 'added', accepted: true) |
rejected-file | VTransmitFile | Fired if the user-supplied accept function returns an error. Fired AFTER the error event to ensure correct file status. (status: 'error', accepted: false) |
accept-complete | VTransmitFile | Fired after the user-supplied accept function has returned regardless of success/failure. Fired after accepted-file & rejected-file. (status: ?, accepted: ?) |
removed-file | VTransmitFile | Fired on the removal of a file. |
thumbnail | VTransmitFile, Blob\|URL | Fires on creation of a thumbnail. |
error | VTransmitFile, message: String, XmlHttpRequest | Fired on an ajax upload error. (status: 'error') |
error-multiple | VTransmitFile[], message: String, XmlHttpRequest | Fired on an ajax upload error. (status: 'error') |
processing | VTransmitFile | Fired after the status is changed to 'uploading', right before the ajax request. |
processing-multiple | VTransmitFile[] | Fired after the status is changed to 'uploading', right before the ajax request. |
upload-progress | VTransmitFile, progress: Number, bytesSent: Number | Fired on progress of the XHR. |
total-upload-progress | VTransmitFile, totalUploadProgress: Number | Fired directly after upload-progress. |
sending | VTransmitFile, XmlHttpRequest, FormData | Fired right before the XHR is sent. |
sending-multiple | VTransmitFile[], XmlHttpRequest, FormData | Fired right before the XHR is sent. |
success | VTransmitFile, response: String, ProgressEvent | Fired on load of the XHR. |
success-multiple | VTransmitFile[], response: String, ProgressEvent | Fired on load of the XHR. |
timeout | VTransmitFile, TimeoutEvent, XmlHttpRequest | Fired on timeout of the XHR. |
timeout-multiple | VTransmitFile[], TimeoutEvent, XmlHttpRequest | Fired on timeout of the XHR. |
canceled | VTransmitFile | Fired upon cancellation of the XHR. (status: 'canceled') |
canceled-multiple | VTransmitFile[] | Fired upon cancellation of the XHR. (status: 'canceled') |
complete | VTransmitFile | Fired upon completion of the XHR. (success or failure) |
complete-multiple | VTransmitFile[] | Fired upon completion of the XHR. (success or failure) |
reset | n/a | Fired when all files have been removed. |
max-files-exceeded | VTransmitFile | Fired if a file is added that exceeds the max files prop. |
max-files-reached | VTransmitFile[] | Fired when the total accepted files on the instance exceeds the max files prop. |
queue-complete | VTransmitFile | Fired once all added files have uploaded and the queue has been flushed. |
Slots
Default ($slots.default)
The default slot should contain your markup for getting an upload started. This could be a file uploader button and/or a dropzone.
Files (Scoped, $slots.files)
This slot receives a number of props:
interface FilesSlotProps {
files: VTransmitFile[];
acceptedFiles: VTransmitFile[];
rejectedFiles: VTransmitFile[];
addedFiles: VTransmitFile[];
queuedFiles: VTransmitFile[];
uploadingFiles: VTransmitFile[];
activeFiles: VTransmitFile[];
isUploading: Boolean;
}VTransmitFile
{
"_nativeFile": {},
"id": "v-transmit-file-1",
"accepted": true,
"lastModified": 1478117443000,
"lastModifiedDate": "2016-11-02T20:10:43.000Z",
"name": "cosmo.jpg",
"processing": true,
"size": 142776,
"status": "success",
"type": "image/jpeg",
"upload": {
"bytesSent": 142776,
"progress": 100,
"speed": {
"kbps": 10.06,
"mbps": 0.01
},
"start": 1503273157993,
"end": 1503273158029,
"time": 0.036,
"total": 142776
},
"webkitRelativePath": "",
"width": 700,
"height": 700,
"xhr": {},
"dataUrl":
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHgAAAB4CAYAAAA5ZDbSAAAgAElEQVR4XlS9B7RmZ3UluG/="
}Usage
If you have PHP installed on your machine, you can clone this repo and open up a working test app by running:
npm testNow navigate to http://localhost:3030/.
<template>
<main id="root" class="mt-5">
<div class="container">
<div class="row">
<header class="col-12 text-center">
<h1 class="mb-5"><code><vue-transmit></code></h1>
</header>
<vue-transmit class="col-12"
tag="section"
v-bind="options"
upload-area-classes="bg-faded"
ref="uploader">
<div class="d-flex align-items-center justify-content-center w-100"
style="height:50vh; border-radius: 1rem;">
<button class="btn btn-primary"
@click="triggerBrowse">Upload Files</button>
</div>
<!-- Scoped slot -->
<template slot="files" scope="props">
<div v-for="(file, i) in props.files" :key="file.id" :class="{'mt-5': i === 0}">
<div class="media">
<img :src="file.dataUrl" class="img-fluid d-flex mr-3">
<div class="media-body">
<h3>{{ file.name }}</h3>
<div class="progress" style="width: 50vw;">
<div class="progress-bar bg-success"
:style="{width: file.upload.progress + '%'}"></div>
</div>
<pre>{{ file | json }} </pre>
</div>
</div>
</div>
</template>
</vue-transmit>
</div>
</div>
</main>
</template>
<script>
Vue.use(VueTransmit)
window.app = new Vue({
el: '#root',
data: {
options: {
acceptedFileTypes: ['image/*'],
url: './upload.php',
clickable: false
}
},
methods: {
triggerBrowse() {
this.$refs.uploader.triggerBrowseFiles()
},
},
filters: {
json(value) {
return JSON.stringify(value, null, 2)
}
}
})
</script>Lifecycle
The upload process has many stages, each with different possible outcomes. Here is an overview of the lifecycle of an upload with Vue Transmit:
- Trigger event
- input on
change: value ofinput.filesis read and passed tovm.addFile - target on
drop: value ofevent.dataTransfer["files" || "items"]is read/traversed and passed tovm.addFile
- input on
- Add File
- instantiate
VTransmitFilefrom native file object (for reactivity & extra info) - status
added - pushed onto
vm.files - thumbnail is enqueued
- instantiate
- Accept File
- check size, type, upload limit
- invoke
acceptfunction for consumer validation acceptorrejectcomplete- if
autoQueue, enqueue file
- Enqueue file
- check that file status is
added& has been accepted - status =
queued - if
autoProcessQueue, invokeprocessQueueasync (like nodesetImmediate)
- check that file status is
- Process queue
- check number of uploading files against upload limit
- invoke
processFileswith max amount of queued files options allow
- Process files
- do upload
- Progress updates
- Complete upload
- status =
success || error - process queue to handle buffered files
- status =
7 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago