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

266
Visualizações
How to fire Watcher, when newValue is the same String?

I'm inserting base64 images into an editor by assigning their base64 string to reactive object state.image and pointing a watcher at it. Problem is that when I want to insert the same image twice, the watcher doesn't fire.

watcher:

const renderImage = (editor) => {
    const unwatch = watch(() => state.image, () => {
        console.log('watcher fires!')
        editor.chain().focus().setImage({ src: state.image }).run()
        unwatch()
        state.image = null
    })
}

As you can see I'm trying to kill the watcher with unwatch() and in addition set state.image = null but it still doesn't fire when the same image is loaded.

The @click event is triggered in this element:

<button  @click="$refs.image.click(); renderImage(editor)"></button>

<input type="file" ref="image" style="display: none" @change="getImageUrl">

and the dataUrl of the image is created in getImageUrl:

const getImageUrl = (event) => {
    const files = event.target.files;
    if (!files.length)
        return;
    const reader = new FileReader();
    reader.onload = (event) => {
        state.image = event.target.result;
    };
    reader.readAsDataURL(files[0]);
}

Both elements seem to work as desired.

How do I make the watcher fire?

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

The question assumes the watch callback isn't firing, but in this case, it's actually the <input> that isn't firing its event.

The <input> only fires the change/input event when its value actually changes. When selecting the same file, the value hasn't changed, and thus no change-event occurs to call the getImageUrl() handler, which would've triggered the watch when the file gets loaded.

To resolve the issue, reset the <input>'s value after copying the selected file's path:

⋮
const image = ref() // template ref on input

const getImageUrl = (event) => {
    const files = event.target.files;
    if (!files.length)
        return;

    const fileToRead = files[0]; // 1️⃣ copy input's value
    image.value.value = null;    // 2️⃣ and reset the input
  
    const reader = new FileReader();
    reader.onload = (event) => {
        state.image = event.target.result;
    };
    reader.readAsDataURL(fileToRead);
}

demo 1

Minor refactoring

renderImage() is actually just using watch to essentially create an async callback for FileReader's load event. It seems this could be simplified by moving the image rendering code into that load-event handler directly:

const getImageUrl = (event) => {
    const files = event.target.files;
    if (!files.length)
        return;

    const fileToRead = files[0];
    image.value.value = null;

    const reader = new FileReader();
    reader.onload = (event) => {
        // 👇 render image
        editor.chain().focus().setImage({ src: event.target.result }).run();
    };
    reader.onerror = reject;
    reader.readAsDataURL(fileToRead);
}

Then you could remove renderImage():

<!-- <button @click="$refs.image.click(); renderImage(editor)"></button> --> <!-- no longer needed -->

<button @click="$refs.image.click()"></button>

...and also state.image:

const state = reactive({
  // image: '' // no longer needed
})

demo 2

about 4 years ago · Juan Pablo Isaza 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