es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo establecer dinámicamente un atributo src de un objeto Image en JavaScript y Vue

Estoy tratando de aprender javascript y Vue.js por mi cuenta. Estaba siguiendo la documentación en el sitio de Vue y modificando sus demostraciones como ejercicio. Quería cambiar su ejemplo de directiva de bucle para agregar imágenes dinámicamente a la lista desde una URL especificada. No parece que se muestre la imagen a pesar de establecer la propiedad src de la imagen. He verificado que todo se ejecuta y que de hecho se establece el campo. Supongo que debo estar entendiendo algo relacionado con el DOM o el orden de los eventos.

Gracias de antemano.

HTML



  1. {{ todo.text }} {{todo.image}}

CSS

.demo {
  font-family: sans-serif;
  border: 1px solid #eee;
  border-radius: 2px;
  padding: 20px 30px;
  margin-top: 1em;
  margin-bottom: 40px;
  user-select: none;
  overflow-x: auto;
}

Javascript

const ListRenderingApp = {
  data() {
    return {
      todos: [
        { text: 'Aprender JavaScript',
          image: new Image(16,16)},
        { text: 'Aprender Vue',
          image: new Image(16, 16)},
        { text: 'Construir algo increíble',
          image: new Image(16, 16)}
      ],
      imgsrc: ''
    }
  },
  methods:{
    setImage(){
      this.todos.map(todo => todo.image.src = this.imgsrc)
    }
  }
}

Vue.createApp(ListRenderingApp).mount('#list-rendering')
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Solución:

    Parece que te falta un listener para los eventos de carga de imágenes. Cuando estableces la propiedad src de una imagen, el navegador comienza a cargar la imagen especificada desde el servidor y esto lleva tiempo completarse. Mientras tanto, el navegador continúa ejecutando el código restante sin esperar a que la imagen se cargue. Esto puede hacer que la imagen no se muestre en la página. Para resolver este problema, debes adjuntar un listener al evento load de la imagen y actualizar el DOM solo después de que la imagen haya terminado de cargar. Puedes modificar el método setImage() para esperar a que la imagen se cargue antes de actualizar el DOM de la siguiente manera:

    methods: {
      setImage() {
        this.todos.map(todo => {
          todo.image.onload = () => {
            // actualizar el DOM solo después de que la imagen se haya cargado
            this.$forceUpdate();
          }
          todo.image.src = this.imgsrc;
        });
      }
    }
    

    Al establecer la propiedad onload de la imagen como una función que actualiza el DOM, te aseguras de que el DOM se actualizará solo después de que la imagen se haya cargado. El método $forceUpdate() se utiliza para provocar manualmente una nueva renderización del componente.

    Alternativamente, puedes utilizar la directiva v-if para renderizar condicionalmente las imágenes solo después de que hayan terminado de cargarse:

    <li v-for="todo in todos">
      {{ todo.text }}
      <img v-if="todo.image" v-bind:src="todo.image.src">
    </li>
    

    Al utilizar la directiva v-if con una condición que verifica si la imagen se ha cargado (todo.image), te aseguras de que la imagen solo se renderice después de que haya terminado de cargarse.

    ¡Espero que esto ayude! Avísame si tienes alguna otra pregunta o problema.

Comments are closed.