Tutorial

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

Published on July 18, 2017
Default avatar

By Bradley Kingsley

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.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Bradley Kingsley

author

Still looking for an answer?

Ask a questionSearch for more help

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?

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel