New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

vue-transmit

Package Overview
Dependencies
Maintainers
1
Versions
67
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vue-transmit

Vue.js drag & drop uploader based on Dropzone.js

  • 9.0.0-alpha.8
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
658
decreased by-45.8%
Maintainers
1
Weekly downloads
 
Created
Source

Vue-Transmit

npm npm downloads GitHub issues GitHub stars Conventional Commits

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. 🙌

Check out the CodeSandbox here: https://codesandbox.io/s/lyzqn4m659

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.

Vue-Transmit also has a modular upload transport. The default transport implementation uses XMLHttpRequest to upload client-side files using multi-part form data, but this could be swapped for a custom implementation for something like Firebase.

In order to integrate with Vue.js reactivity, an object's properties must be defined initially, be enumerable, and be configurable. A special File class has been written (VTransmitFile) to register native browser file objects from uploads reactively, since the native object 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
  • Modular upload transport layer
  • 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, Promise) that require a polyfill. All other ESNext language features (arrow fns, for of, etc.) are transpiled with TypeScript.

upload-example

v8.x.x

Visit the 8.x branch here.

Version 9 of Vue Transmit marks a new design that introduces various breaking changes. Migrating an existing app to >=v9.x.x should be roughly hour of work for most use cases (mileage may vary), but if you're using v8.x.x and you don't need any v9 features, there's no need to update. An 8.x branch will be maintained for LTS* support.

* LTS support === patches only.

Installation

npm install vue-transmit

Builds

The default build for ESM loaders like webpack is indicated in the module field of the package, while non-esm will resolve from the main field. By default, the unminified versions are specified. For most setups, importing the lib would like either of the following:

// ESM
import { VueTransmitPlugin } from "vue-transmit";
// Common.js
const { VueTransmitPlugin } = require("vue-transmit");
// Browser
const VueTransmitPlugin = window.VueTransmit.VueTransmitPlugin;

// Installation
Vue.use(VueTransmit);

If you don't wish to register VueTransmit as a global component, you can import the component directly.

// ESM
import { VueTransmit } from "vue-transmit";
// Common.js
const { VueTransmit } = require("vue-transmit");
// Browser
const VueTransmit = window.VueTransmit.VueTransmit;

// Your component using VueTransmit
const MyComponent = Vue.extend({
  name: "my-component",
  components: {
    "vue-transmit": VueTransmit,
  },
});
TargetPathMinified
ESMvue-transmit/dist/vue-transmit.esm.jsfalse
ESMvue-transmit/dist/vue-transmit.esm.min.jstrue
UMDvue-transmit/dist/vue-transmit.jsfalse
UMDvue-transmit/dist/vue-transmit.min.jstrue

Props: <vue-transmit>

View Source

PropertyTypeDefault
tagString"div"
uploadAreaClassesArray, Object, Stringnull
uploadAreaAttrsObject[Function: objFactory]
uploadAreaListenersObject[Function: objFactory]
dragClassStringnull
maxConcurrentUploadsNumber2
uploadMultipleBooleanfalse
maxFileSizeNumber256
fileSizeBaseInBinaryBooleanfalse
createImageThumbnailsBooleantrue
maxThumbnailFileSizeNumber10
thumbnailWidthNumber120
thumbnailHeightNumber120
maxFilesNumbernull
clickableBooleantrue
ignoreHiddenFilesBooleantrue
acceptedFileTypesArray[Function: default]
autoProcessQueueBooleantrue
autoQueueBooleantrue
captureStringnull
errMaxFileSizeExceededFunction[Function: default]
errInvalidFileTypeFunction[Function: default]
errMaxFilesExceededFunction[Function: default]
acceptFunction[Function: default]
resizeFunction[Function: resizeImg]
adapterOptionsObject[Function: objFactory]
uploadAdapterFunction[Function: XHRUploadAdapter]

Adapter Options: XHRUploadAdapter

View Source

PropertyTypeDefault
urlstring(required)
methodstring"post"
withCredentialsbooleanfalse
timeoutnumber0
paramNamestring"file"
paramsobject{}
headersobject{ Accept, 'Cache-Control', 'X-Requested-With' }
responseTypestring"json"
errUploadErrorfunction[Function]
errUploadTimeoutfunction[Function]
renameFilefunction[Function]

Events

EventArgumentsDescription
dropDragEventThe drop event is fired when an data transfer is dropped on the drop target.
drag-startDragEventThe drag-start event is fired when the user starts dragging an element or text selection.
drag-endDragEventThe drag-end event is fired when a drag operation is being ended (by releasing a mouse button or hitting the escape key).
drag-enterDragEventThe drag-enter event is fired when a dragged element or text selection enters a valid drop target.
drag-overDragEventThe drag-over event is fired when an element or text selection is being dragged over a valid drop target (every few hundred milliseconds).
drag-leaveDragEventThe drag-leave event is fired when a dragged element or text selection leaves a valid drop target.
added-fileVTransmitFileFired 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-filesVTransmitFile[]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-fileVTransmitFileFired if the user-supplied accept function returns without error. (status: 'added', accepted: true)
rejected-fileVTransmitFileFired if the user-supplied accept function returns an error. Fired AFTER the error event to ensure correct file status. (status: 'error', accepted: false)
accept-completeVTransmitFileFired after the user-supplied accept function has returned regardless of success/failure. Fired after accepted-file & rejected-file. (status: ?, accepted: ?)
removed-fileVTransmitFileFired on the removal of a file.
thumbnailVTransmitFile, Blob|URLFires on creation of a thumbnail.
errorVTransmitFile, message: String, XmlHttpRequestFired on an ajax upload error. (status: 'error')
error-multipleVTransmitFile[], message: String, XmlHttpRequestFired on an ajax upload error. (status: 'error')
processingVTransmitFileFired after the status is changed to 'uploading', right before the ajax request.
processing-multipleVTransmitFile[]Fired after the status is changed to 'uploading', right before the ajax request.
upload-progressVTransmitFile, progress: Number, bytesSent: NumberFired on progress of the XHR.
total-upload-progressVTransmitFile, totalUploadProgress: NumberFired directly after upload-progress.
sendingVTransmitFile, XmlHttpRequest, FormDataFired right before the XHR is sent.
sending-multipleVTransmitFile[], XmlHttpRequest, FormDataFired right before the XHR is sent.
successVTransmitFile, response: String, ProgressEventFired on load of the XHR.
success-multipleVTransmitFile[], response: String, ProgressEventFired on load of the XHR.
timeoutVTransmitFile, TimeoutEvent, XmlHttpRequestFired on timeout of the XHR.
timeout-multipleVTransmitFile[], TimeoutEvent, XmlHttpRequestFired on timeout of the XHR.
canceledVTransmitFileFired upon cancellation of the XHR. (status: 'canceled')
canceled-multipleVTransmitFile[]Fired upon cancellation of the XHR. (status: 'canceled')
completeVTransmitFileFired upon completion of the XHR. (success or failure)
complete-multipleVTransmitFile[]Fired upon completion of the XHR. (success or failure)
resetn/aFired when all files have been removed.
max-files-exceededVTransmitFileFired if a file is added that exceeds the max files prop.
max-files-reachedVTransmitFile[]Fired when the total accepted files on the instance exceeds the max files prop.
queue-completeVTransmitFileFired 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 test

Now 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>&lt;vue-transmit&gt;</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" slot-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/*'],
        clickable: false,
        adapterOptions: {
          url: './upload.php',
        },
      }
    },
    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 of input.files is read and passed to vm.addFile
    • target on drop: value of event.dataTransfer["files" || "items"] is read/traversed and passed to vm.addFile
  • Add File
    • instantiate VTransmitFile from native file object (for reactivity & extra info)
    • status added
    • pushed onto vm.files
    • thumbnail is enqueued
  • Accept File
    • check size, type, upload limit
    • invoke accept function for consumer validation
    • accept or reject complete
    • if autoQueue, enqueue file
  • Enqueue file
    • check that file status is added & has been accepted
    • status = queued
    • if autoProcessQueue, invoke processQueue async (like node setImmediate)
  • Process queue
    • check number of uploading files against upload limit
    • invoke processFiles with max amount of queued files options allow
  • Process files
    • do upload
  • Progress updates
  • Complete upload
    • status = success || error
    • process queue to handle buffered files

Keywords

FAQs

Package last updated on 22 Feb 2018

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc