Home  >  Q&A  >  body text

Implement Vue loading animation and load images from URL at the same time

<p>I want to show a loading animation when the image loads, but I don't know how to achieve it. <br /><br />Although there is no loader, I debugged and "true" and "false" were displayed on the console, but still no loading animation appeared. </p><p><br /></p> <pre class="brush:php;toolbar:false;"><template> <div class="KingOfMountain"> <Spinner v-if="isLoading"/> //// ERROR <div v-else class="container"> <div v-if="!isEndGameKing" class="choices"> <p id="score">{{ currentCountKing }}/{{ ALL_FILMS.length - 1 }} <p/> <div class="photos"> <div class="first__film"> <img :src="firstFilm.Poster" :alt="firstFilm.title" @click="chooseLeftFilm"> <p id="title--film">{{ firstFilm.title }}</p> </div> <div class="second__film"> <img :src="secondFilm.Poster" :alt="secondFilm.title" @click="chooseRightFilm"> <p id="title--film">{{ secondFilm.title }}</p> </div> </div> </div> <div v-else class="winner"> <p id="winner--title">Победитель</p> <img :src="firstFilm.Poster" :alt="firstFilm.title"> </div> </div> </div> </template> <script> import game from "@/mixins/game"; import Spinner from "@/components/Spinner/Spinner"; //all good in css . it works export default { name: "KingOfMountain", data() { return{ isLoading:false } }, components: {Spinner}, methods: { chooseLeftFilm() { this.isLoading=true this.redirectToResultKing() // it is method in mixins (all Good, it works) this.isLoading=false }, chooseRightFilm() { this.isLoading=true this.firstFilm = this.secondFilm; this.redirectToResultKing() // it is method in mixins (all Good, it works) this.isLoading=false } }, } </script></pre> <p>如果我像这样使用,它会显示加载动画:</p> <pre class="brush:php;toolbar:false;">chooseLeftFilm() { this.isLoading=true this.redirectToResultKing() // it is method in mixins (all Good, it works) },</pre> <p>// it will spinner forever</p> <p>帮我,如何更好地制作加载动画?</p> <p>我的混入(mixins):</p> <pre class="brush:php;toolbar:false;">export default { methods: { updateFilm() { // Here i random take 2 images from Vuex and then them delete and etc... this.currentCountKing ; this.allFilmsKingCopy = this.allFilmsKingCopy.filter(val => val !== this.secondFilm) this.secondFilm = this.allFilmsKingCopy[Math.floor(Math.random() * this.allFilmsKingCopy.length)] }, redirectToResultKing() { if (this.currentCountKing === this.ALL_FILMS.length - 1) { this.isEndGameKing = true } else { this.updateFilm() } } }, computed: { ...mapGetters(['ALL_FILMS']), },</pre> <p>我的 Vuex:</p> <pre class="brush:php;toolbar:false;">export default { state: { films: [], }, actions: { async getFilms({commit}) { const data = await fetch(URL); const dataResponse = await data.json(); const films=dataResponse.data commit("setData", films) }, }, mutations: { setData(state, films) { state.films = films }, }, getters: { ALL_FILMS(state) { return state.films }, } }</pre> <p><br /></p>
P粉021854777P粉021854777421 days ago560

reply all(1)I'll reply

  • P粉588660399

    P粉5886603992023-08-04 13:43:52

    The common method is to use the Image object to load the image, then use the load event to wait for the data to be loaded, and display the loading animation during the loading process. You can then set the URL of the image and it will update immediately:


    const imgUrl = 'https://picsum.photos/200?random='
    let imgCount = 0
    
    const App = {
      template: `
        <div style="display: flex;">
          <div>
            <button @click="loadImage">Load new image</button>
          </div>
          <div v-if="isLoading">LOADING....</div>
          <img :src="src"/>
        </div>
      `,
      data() {
        return {
          isLoading: false,
          src: null,
        }
      },
      methods: {
        async loadImage() {
          this.src = null
          this.isLoading = true
          const img = new Image()
          img.src = imgUrl + imgCount++
          await new Promise(resolve => img.onload = resolve)
          this.src = img.src
          this.isLoading = false
        }
      },
      created() {
        this.loadImage()
      },
    }
    Vue.createApp(App).mount('#app')
    <div id="app"></div>
    <script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>

    reply
    0
  • Cancelreply