Image Upload
This page show an example of a Reusable Image Upload Component. The idea is to help with all the logic you will possibly need to implement image upload functionality and focus on just the UI.
This is still a work in progress
Dependencies
{
"tailwindcss": "^3.3.2", // for styling
}
Props
These are the props passed into the ImageUpload component
inputId
- Type:
String
This is to target the hidden input field outside the component
multiple
- Type:
Boolean
- default:
fasle
If you want to upload multiple images, you can set this to true. And yes you don't have to worry about the logic
accept
- Type:
Array
- default:
['image/*']
This is to signify the image format you want. It has to be the same as default accept format (i.e .jpg, .png, etc)
Events
@uploaded(value: string | string[] | ArrayBuffer | null, file: FileList | null | undefined)
This fires after a successful upload. It returns both image src and the fileList so you can use however you want
Demo
Code
vue
<template>
<div>
<!-- Choose to use this particular UI. You can implement your UI however you want -->
<ImageUpload input-id="img_file_input" v-slot="{ hasUpload, deleteUpload }" @uploaded="imageSrc">
<div class="bg-white text-center text-black rounded px-4 py-2 w-1/5">
<label for="img_file_input" class="italic">Select Image</label>
</div>
<div v-show="hasUpload" class="group relative w-40 h-40 my-2">
<img ref="imgRef" alt="Random Image" class="w-full h-full object-contain">
<svg
class="absolute hidden top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 group-hover:block cursor-pointer"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 24 24"
@click="deleteUpload"
>
<path fill="#ef4444" d="M6 20V6H5V5h4v-.77h6V5h4v1h-1v14zm1-1h10V6H7zm2.808-2h1V8h-1zm3.384 0h1V8h-1zM7 6v13z"/>
</svg>
</div>
</ImageUpload>
</div>
</template>
<script setup lang="ts">
import { ref, Ref } from 'vue'
import ImageUpload from '../components/ImageUpload/ImageUpload.vue';
const imgRef = ref() as Ref<HTMLImageElement>
const imageSrc = (value: string | string[] | ArrayBuffer | null, value2: FileList | undefined | null) => {
imgRef.value.setAttribute('src', value)
}
</script>
<style scoped>
</style>
vue
<template>
<div>
<!-- Choose to use this particular UI. You can implement your UI however you want -->
<ImageUpload
input-id="multiple_img_file_input"
multiple
v-slot="{ hasUpload, deleteUpload }"
:accept="['image/*']"
@uploaded="uploadFunc"
>
<div class="bg-white text-center text-black rounded px-4 py-2 w-1/3 my-4">
<label for="multiple_img_file_input" class="italic">Select multiple Image</label>
</div>
<div v-show="hasUpload" class="flex items-center gap-4">
<div v-for="(data, idx) in uploadData" :key="idx" class="group relative w-40 h-40 my-2">
<img ref="imgRef" :src="data" alt="Random Image" class="w-full h-full object-contain">
<svg
class="absolute hidden top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 group-hover:block cursor-pointer"
xmlns="http://www.w3.org/2000/svg"
width="32"
height="32"
viewBox="0 0 24 24"
@click="deleteUpload(idx)"
>
<path fill="#ef4444" d="M6 20V6H5V5h4v-.77h6V5h4v1h-1v14zm1-1h10V6H7zm2.808-2h1V8h-1zm3.384 0h1V8h-1zM7 6v13z"/>
</svg>
</div>
</div>
</ImageUpload>
</div>
</template>
<script setup lang="ts">
import { ref, Ref } from 'vue'
import ImageUpload from '../components/ImageUpload/ImageUpload.vue';
const uploadData = ref([])
const uploadFunc = (value: string | string[] | ArrayBuffer | null) => {
uploadData.value = value
}
</script>
<style scoped>
</style>