Skip to content

Instantly share code, notes, and snippets.

@shivanshtalwar0
Created April 6, 2023 10:38
Show Gist options
  • Save shivanshtalwar0/c57000f4d917a03c1ea552df85f94857 to your computer and use it in GitHub Desktop.
Save shivanshtalwar0/c57000f4d917a03c1ea552df85f94857 to your computer and use it in GitHub Desktop.
Asynchronously load image through Promise in vue js with directive

Create Global Directive

const vueApp=createApp({})
const replaceElementChildrenWithImage = async (el, binding ) => {
    try {
      const image = await binding.value;
      if (image) el.replaceChildren(image);
    } catch (err) {
      console.error("Image can't be resolved seems like url is broken",err);
    }
};
vueApp.directive("asyncImage", {
    updated: async (el, binding) => {
      await replaceElementChildrenWithImage(el, binding);
    },
    created: async (el, binding) => {
      await replaceElementChildrenWithImage(el, binding);
    },
});

Inside Vue Component

<template>
  <div v-async-image="asyncImage"></div>
<template>  
<script setup lang="ts">
import {ref,onMounted} from 'vue'
const asyncImage=ref<Promise<HtmlImageElement>>()
onMounted(()=>{
  setInterval(
        ()=>{
          asyncImage.value=getImageByUrl(`https://picsum.photos/200/300?${Math.random()*100000}`)
  },2000);
});

function getImageByUrl(url){
return new Promise((resolve,reject)=>{
  const image=new Image()
  image.onLoad=()=>{
  resolve(image)
  }
  image.onError=(event)=>{
  reject(event)
  }
  image.src=url;
  })
}
</script>  
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment