Cómo subir una imagen a Cloudinary  con VueJS

Cómo subir una imagen a Cloudinary con VueJS

Guía paso a paso para integrar Cloudinary en tu aplicación VueJS y subir imágenes de forma fácil y segura

Introducción

VueJS es un framework JavaScript para crear interfaces de usuario interactivas y modernas. Es conocido por su simplicidad, flexibilidad y rendimiento. VueJS se basa en el concepto de componentes, lo que facilita la creación de aplicaciones web modulares y escalables.

Cloudinary es una plataforma SaaS que te permite administrar, optimizar y entregar imágenes y videos en tu sitio web o aplicación móvil.

En este tutorial, aprenderás a crear una aplicación VueJS con un formulario para subir una imagen a Cloudinary. Te guiaré paso a paso a través del proceso, desde la configuración de Cloudinary hasta la subida de la imagen y su visualización en tu aplicación.

Al final de este tutorial, serás capaz de:

  • Registrarte en Cloudinary y obtener tus claves API.

  • Instalar las dependencias necesarias en tu proyecto VueJS.

  • Configurar Cloudinary en tu aplicación VueJS.

  • Crear un formulario para seleccionar y subir una imagen.

  • Obtener la URL de la imagen y mostrarla en tu aplicación.

Concideraciones

Este tutorial va dirigido a desarrolladores web con conocimientos básicos de VueJS y que buscan aprender a usar Cloudinary para subir imágenes en sus aplicaciones VueJS.

Requisitos previos:

  • Tener instalado NodeJS y npm.

  • Tener conocimientos básicos de VueJS.

Creación del proyecto

Para crear un proyecto VueJS ejecuta el siguiente comando:

npm create vite@latest vuejs-cloudinary -- --template vue

Este comando creará un directorio vuejs-cloudinary , entra al directorio e instala las dependencias con npm install .

Vamos a usar bootstrap para los estilos, lo instalamos con el comando npm install bootstrap , luego modificamos el fichero src/main.js como sigue:

import 'bootstrap/dist/css/bootstrap.css'

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

Creamos el componente src/components/Form.vue para el formulario:

<template>
  <form>
    <div class="form-group py-2 text-center">
        <div style="width: 350px;height: auto;" class="mx-auto">
            <img src="https://fakeimg.pl/350x200/" alt="avatar" id="preview" class="img-thumbnail mb-2 mx-auto" />
        </div>
      <input type="file" id="image" class="form-control-file"/>
    </div>
    <div class="form-group py-2 d-grid">
        <button type="submit" class="btn btn-primary">Enviar</button>
    </div>
  </form>
</template>

Ahora lo incorporamos a src/App.vue .

<script setup>
import Form from './components/Form.vue';
</script>

<template>
  <div class="container">
    <div class="row justify-content-center">
      <div class="col-md-6">
        <h1 class="text-center display-3">Subir imagen</h1>
        <hr>
        <Form />
      </div>
    </div>
  </div>
</template>

En este punto deberías tener la siguiente pantalla:

El modo oscuro de bootstrap se puede establecer añadiendo el atributo data-bs-theme="dark" a la etiqueta html del fichero index.html.

Tenemos un formulario con un input de tipo file, y un elemento img que nos sirve como vista previa de la imagen que vamos a subir.

Ahora vamos a añadir la funcionalidad para que cuando seleccionemos una imagen, esta se muestre en el elemento de vista previa. Crea la siguiente función en el componente src/components/Form.vue :

<script setup>
function handleFileChange(event) {
  var file = event.target.files[0];
  var url = URL.createObjectURL(file);
  document.querySelector('img').src = url;
};
</script>

var file = event.target.files[0]; : Obtiene el primer archivo seleccionado del elemento de entrada.

var url = URL.createObjectURL(file);: Crea una URL temporal para el archivo seleccionado.

document.querySelector('img').src = url;: Encuentra la primer etiqueta img y le pasa la url temporal a su atributo src.

Ahora debemos vincular la función al evento change del elemento input file, con la siguiente línea:

<input type="file" id="image" class="form-control-file"
                                        @change="handleFileChange"/>

Ahora, cuando selecciones una imagen, podrás verlo en el elemento de vista previa antes de enviar el formulario.

Continuamos con la función que se encargará de enviar el formulario:

<script setup>
import { ref } from 'vue';

const fileInput = ref(null);

function handleSubmit(){
  const file = fileInput.value.files[0];
  console.log("Archivo seleccionado: ", file);
}

Por ahora, la función solo muestra la información de la imagen por consola. Vinculamos la variable reactiva fileInput con el campo image como sigue:

<input type="file" id="image" class="form-control-file"
                                        @change="handleFileChange"
                                        ref="fileInput"/><!-- Vinculamos elcampo
con la variable reactiva fileInput-->

Ahora vinculamos la función handleSubmit al formulario como sigue:

<form @submit.prevent="handleSubmit">

Ahora, al presionar el botón enviar, podrás ver los datos de la imagen por consola.

Ya tenemos todo listo para comenzar a trabajar con Cloudinary.

Cloudinary

Entra a cloudinary y crea una cuenta. Una vez registrado podrás ingresar al dashboard. Toma nota del cloud name, es un identificador único para el entorno de tu producto Cloudinary. Piensa en ello como el nombre que le da a su espacio de trabajo específico en la plataforma Cloudinary. Lo vamos a utilizar mas tarde para subir imágenes y acceder a ellos.

Vamos a crear una carpeta para almacenar nuestras imágenes. Entra a la opción "Assets" y luego en "Folders". Haz clic en el ícono de crear carpeta y llámalo "images_vuejs".

Ahora debemos definir un el presets que vamos a utilizar. Haz clic en el ícono de settings que está en la esquina inferior izquierda, y entra en la opción "Upload". Ver a la sección "Upload presets" haz clic en la opción "Add upload preset". Vamos a cambiar el nombre por defecto por el nombre de la carpeta que creamos para nuestras imágenes, en "Signing Mode" elegimos la opción "Usigned", finalmente en la opción "Folder" colocamos el nombre de la carpeta que creamos.

Ya tenemos todo listo para empezar a subir imágenes.

Subir imagen a Cloudinary

Vamos a modificar la función handleSubmit como sigue:

async function handleSubmit() {
  const file = fileInput.value.files[0];
  const cloudname = "dezkmxexp";
  const formData = new FormData();
  formData.append('file', file);
  formData.append('upload_preset', 'images_vuejs');

  try {
    const response = await fetch(`https://api.cloudinary.com/v1_1/${cloudname}/image/upload`, {
      method: 'POST',
      body: formData
    });
    const data = await response.json();
    console.log("Archivo subido con éxito: ", data);
  } catch (error) {
    console.error("Error al subir el archivo: ", error);
  }
}

Esta función permite enviar un archivo seleccionado en el formulario a Cloudinary utilizando su API y el preset configurado. Definimos la función como asíncrona con "async/await".

La línea const cloudname = "dezkmxexp"; define la variable con el valor de nuestro cloudname de Cloudinary. Ten en cuenta que deberías reemplazar este valor con tu propio nombre de nube de Cloudinary.

Se crea un objeto formData del tipo FormData. Este objeto se utiliza para enviar datos de formulario, incluyendo archivos, a un servidor.

Se utilizan dos métodos append del objeto formData para agregar datos al formulario:

  • El primer append agrega el archivo seleccionado (file) con la clave 'file'.

  • El segundo append agrega una cadena de texto "images_vuejs" con la clave 'upload_preset'. Este valor del preset debe coincidir con el preset que configuramos previamente en la cuenta de Cloudinary.

Se utiliza la función fetch para realizar una petición POST a la API de Cloudinary.

  • La URL de la petición se construye con el nombre de la nube (cloudname) y la ruta /v1_1/${cloudname}/image/upload.

  • El método de la petición se establece como 'POST'.

  • El cuerpo de la petición se configura con el objeto formData creado anteriormente.

Si la petición es exitosa (código de estado 200), se espera la respuesta en formato JSON y se almacena en la variable data.

console.log("Archivo subido con éxito: ", data); si la petición es exitosa, se imprime un mensaje en la consola indicando el éxito de la subida y se muestran los datos de la respuesta (la información de la imagen subida).

Ya podemos subir imágenes a nuestra cuenta de Cloudinary. Dentro del objeto que nos retorna, podemos encontrar una url por el cual podemos acceder a la imagen que acabamos de subir. Vamos a crear un componente visor para mostrar esta imagen.

Visor de imagen

Creamos el componente src/components/Viewer.vue :

<script setup>
    const props = defineProps(['urlImage']);
</script>
<template>
    <img :src="props.urlImage" alt="visor" class="img-thumbnail mb-2 mx-auto" />
</template>

Se define una propiedad llamada urlImage utilizando defineProps. Esta propiedad espera recibir una cadena de texto que representa la URL de la imagen a mostrar.

En src/App.vue importamos el componente que creamos.

<script setup>
import { ref } from 'vue';
import Form from './components/Form.vue';
import Viewer from './components/Viewer.vue';

const url_image = ref("https://fakeimg.pl/600x300/");
</script>

<template>
  <div class="container">
    <div class="row justify-content-center">
      <div class="col-md-6">
        <h1 class="text-center display-3">Subir imagen</h1>
        <hr>
        <Form />
      </div>
    </div>
    <div class="row justify-content-center">
      <div class="col-md-6 text-center">
        <Viewer :urlImage="url_image"/>
      </div>
    </div>
  </div>
</template>

Importamos el componente src/components/Viewer.vue y lo incorporamos a la vista principal de la aplicación. Definimos una variable reactiva llamada url_image con un valor inicial, que es una URL que apunta a un servicio que genera imágenes falsas (fakeimg.pl). En este caso, la URL genera una imagen con un tamaño de 600x300 píxeles.

El componente Viewer muestra la imagen cuya URL se encuentra en la variable reactiva url_image. Si el valor de url_image cambia posteriormente, la imagen que se muestra en el componente Viewer se actualizará automáticamente.

Modificamos el componente src/components/Form.vue como sigue:

<script setup>
import { ref, defineEmits } from 'vue';

const emit = defineEmits(['getUrlImage']);//Definimos un evento

const fileInput = ref(null);

async function handleSubmit() {
  const file = fileInput.value.files[0];
  const cloudname = "dezkmxexp";
  const formData = new FormData();
  formData.append('file', file);
  formData.append('upload_preset', 'images_vuejs');

  try {
    const response = await fetch(`https://api.cloudinary.com/v1_1/${cloudname}/image/upload`, {
      method: 'POST',
      body: formData
    });
    const data = await response.json();
    console.log("Archivo subido con éxito: ", data);
    //Actualiza la imagen de la vista previa
    document.getElementById('preview').src = "https://fakeimg.pl/350x200/";
    emit('getUrlImage', data.secure_url);//Emite el evento y pasamos la url que cloudinary nos retorna

  } catch (error) {
    console.error("Error al subir el archivo: ", error);
  }
}


function handleFileChange(event) {
  var file = event.target.files[0];
  var url = URL.createObjectURL(file);
  document.querySelector('img').src = url;
};
</script>
<template>
    <form @submit.prevent="handleSubmit">
      <div class="form-group py-2 text-center">
        <div style="width: 350px;height: auto;" class="mx-auto">
            <img src="https://fakeimg.pl/350x200/" alt="avatar" id="preview" class="img-thumbnail mb-2 mx-auto" />
        </div>
        <input type="file" id="image" class="form-control-file" @change="handleFileChange" ref="fileInput"/>
      </div>
      <div class="form-group py-2 d-grid">
          <button type="submit" class="btn btn-primary">Enviar</button>
      </div>
    </form>
  </template>

Las modificaciones que introdujimos son las siguientes:

  • const emit = defineEmits(["getUrlImage"]);: definimos un evento que estaremos utilizando para comunicarnos con el componente padre. En este caso debemos enviar la url de nos retorna el API Cloudinary.

  • document.getElementById('preview').src = "https://fakeimg.pl/350x200/"; : actualizamos la vista previa.

  • emit('getUrlImage', data.secure_url); : emitimos el evento 'getUrlImage' y enviamos la url que nos retorna el API Cloudinary con el cual vamos a actualizar el elemento Viewer.vue .

Volvemos al componente src/App.vue y realizamos las siguientes modificaciones:

<script setup>
import { ref } from 'vue';
import Form from './components/Form.vue';
import Viewer from './components/Viewer.vue';

const url_image = ref("https://fakeimg.pl/600x300/");

// Actualiza la variable reactiva 'url_image' con la url de Cloudinary
function getUrlImage(url) {
  url_image.value = url;
}
</script>

<template>
  <div class="container">
    <div class="row justify-content-center">
      <div class="col-md-6">
        <h1 class="text-center display-3">Subir imagen</h1>
        <hr>
        <Form @getUrlImage="getUrlImage"/><!-- Escucha el evento 'getUrlImage'-->
      </div>
    </div>
    <div class="row justify-content-center">
      <div class="col-md-6 text-center">
        <Viewer :urlImage="url_image"/>
      </div>
    </div>
  </div>
</template>

Introdujimos los siguientes cambios:

  •     function getUrlImage(url) {
          url_image.value = url;
        }
    

    Esta función se encarga de actualizar la variable reactiva 'url_image' con la url que nos retorna la API de Cloudinary.

  •     <Form @getUrlImage="getUrlImage"/>
    

    Escuchamos el evento 'getUrlImage'. Cuando el elemento Form emita el evento se ejecuta la función 'getUrlImage' que definimos anteriormente. Esto permitirá actualizar el elemento Viewer con la imagen que acabamos de subir a Cloudinary.

Conclusión

Hemos finalizado con el tutorial; en este viaje hemos aprendido los fundamentos básicos de VueJS. Como crear componentes, como utilizar las directivas, como definir y usar eventos, comunicar datos entre componentes, etc.

Aprendimos como integrar nuestra aplicación con la API de Cloudinary y subir imágenes a nuestra cuenta y como acceder a la url que nos retorna.

Espero que este tutorial haya sido útil y te haya proporcionado una base sólida para construir aplicaciones con VueJS.

Puedes encontrar el proyecto completo en mi repositorio de GitHub haciendo clic AQUÍ.

Espero que lo hayas encontrado entretenido, instructivo y claro. Si tienes alguna duda, puedes hacérmelo saber en los comentarios. Pronto estaré subiendo más tutoriales.

Nos vemos en la próxima. Saludos!👋😊