Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

137
Visualizações
How to make reactivity work with a Promise started from a constructor?

I have a class Thing, whose constructor starts an asynchronous fetch operation. When the fetch completes, the result is assigned to a field on the Thing object:

  class Thing {
    constructor() {
      this.image = null
      this.load()
    }

    async load() {
      const response = await fetch('https://placekitten.com/200/300')
      const blob = await response.blob()
      this.image = await createImageBitmap(blob)
    }
  }

I'm using thing.image in a Vue component. The problem is that Vue doesn't pick up on the change in image when the Promise resolves. I think I understand why this happens: in the constructor, this refers to the raw Thing, and not Vue's reactive proxy wrapper. So the assignment to this.image ends up bypassing the proxy.

It works if I move the load call out of the constructor, so that this inside the load function refers to the reactive proxy. But that makes my Thing class harder to use.

Is there a better way to handle this issue?

Minimal example (Vue playground link):

<script setup>
  import { reactive } from 'vue'

  class Thing {
    constructor() {
      this.image = null
      this.load() // This does not trigger reactivity.
    }

    async load() {
      const response = await fetch('https://placekitten.com/200/300')
      const blob = await response.blob()
      this.image = await createImageBitmap(blob)
    }
  }

  const thing = reactive(new Thing())
  // thing.load() // This triggers reactivity as expected.
</script>

<template>
  <p v-if="thing.image">
    Image size is {{thing.image.width}}×{{thing.image.height}}
  </p>
  <p v-if="!thing.image">
    Loading...
  </p>
</template>
about 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

define your class attribute as a ref

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

  class Thing {
    constructor() {
      this.image = ref(null)
      this.load()
    }

    async load() {
      const response = await fetch('https://placekitten.com/200/300')
      const blob = await response.blob()
      this.image.value = await createImageBitmap(blob)
    }
  }

  const thing = reactive(new Thing())
  // thing.load() // This triggers reactivity as expected.
</script>

<template>
  <p v-if="thing.image">
    Image size is {{thing.image.width}}×{{thing.image.height}}
  </p>
  <p v-if="!thing.image">
    Loading...
  </p>
</template>
about 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda