// Tutorial //

Image Upload in Your Vue.js Apps With vue-picture-input

Published on July 18, 2017
Default avatar
By Bradley Kingsley
Developer and author at DigitalOcean.
Image Upload in Your Vue.js Apps With vue-picture-input

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

File and image uploads are a must-have feature for many non-trivial apps. Lucky for us, it’s easy to setup in Vue apps with vue-picture-input.

Check this post of ours if you’re looking to create your own custom file selector input.

Installation

Install vue-picture-input via npm or Yarn:

$ npm install --save vue-picture-input

# or:
$ yarn add vue-picture-input

Usage

The vue-picture-input library allows for a variety of usages, and is very simple to use:

<template>
  <picture-input

  <!--Props go here-->

  ></picture-input>
</template>

Here are a few props that we’re going to make use of:

  • ref: We’ll need this to access the base64 image string
  • width, height: Dictate the width and height of the component
  • accept: Used to restrict accepted file types
  • removable: Specifies whether the component can be reset or not

Additionally, the component emits the following events:

  • removed: emitted when picture is detached from component
  • changed: emitted when the selected picture is changed (ie. reselected)

Here’s what our code looks like for the file input:

index.vue
<picture-input
  ref="pictureInput"
  @change="onChanged"
  @remove="onRemoved"
  :width="500"
  :removable="true"
  removeButtonClass="ui red button"
  :height="500"
  accept="image/jpeg, image/png, image/gif"
  buttonClass="ui button primary"
  :customStrings="{
  upload: '<h1>Upload it!</h1>',
  drag: 'Drag and drop your image here'}">

</picture-input>

Let’s add a button that will allow us to upload the selected image to our backend.

It basically calls the attemptUpload method when clicked and has the disabled class binding. It’ll only be enabled if there’s a selected image:

<button @click="attemptUpload" v-bind:class="{ disabled: !image }">
  Upload
</button>

Next, we’ll use Axios to make network requests. We’ll also leverage the Formdata API to create a sweet composition for posting image data:

upload.js
import axios from 'axios';

export default function (url, file, name = 'avatar') {
  if (typeof url !== 'string') {
    throw new TypeError(`Expected a string, got ${typeof url}`);
  }

  // You can add checks to ensure the url is valid, if you wish

  const formData = new FormData();
  formData.append(name, file);
  const config = {
    headers: {
      'content-type': 'multipart/form-data'
    }
  };
  return axios.post(url, formData, config);
};

The above code accepts a url as the first parameter and a file object as the second parameter then returns a promise. It also sets the header’s content-type to multipart/formdata so our backend API can tell what’s in the pipes.

We can therefore use the above code as so:

import FormDataPost from '/upload';

//...

FormDataPost('http://localhost:8001/user/picture', image)
  .then(response=>{
    console.log("Uploaded picture successfully");
  })
  .catch(err=>{
    console.error(err);
  });

 //...

Here’s what our onChanged, onRemoved and attemptUpload methods look like:

//...

methods: {
  onChanged() {
    console.log("New picture loaded");
    if (this.$refs.pictureInput.file) {
      this.image = this.$refs.pictureInput.file;
    } else {
      console.log("Old browser. No support for Filereader API");
    }
  },
  onRemoved() {
    this.image = '';
  },
  attemptUpload() {
    if (this.image){
      FormDataPost('http://localhost:8001/user/picture', this.image)
        .then(response=>{
          if (response.data.success){
            this.image = '';
            console.log("Image uploaded successfully ✨");
          }
        })
        .catch(err=>{
          console.error(err);
        });
    }
  }
}

//...

💪 Done! Our image upload is working on the frontend. Read-on for how to set this up on a Node.js backend using Express.


Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?
1 Comments

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!

Hi, Thanks for your contribution. Is there a way to add resizing of the images in the UI with this code as starting point? Is there perhaps a library for such features?