Reputation: 23
I'm very new to vue. what I'm trying to do is have a loading gif while waiting for the endpoint to return.
I'm trying to use watchEffect, but I can't figure it out. If it's the right way how do I do it? If not what should I use instead?
Thanks
EDIT: Code
<template>
<div class="player-list" :key="playerList.id" v-for="playerList in players.playerLists">
<PlayerList :playerList="playerList" />
</div>
</template>
<script>
import getPlayers from "@/composables/getPlayers";
import PlayerList from "@/components/PlayerList";
import { watchEffect } from 'vue';
export default {
name: 'PlayerLists',
components: {
PlayerList
},
setup() {
const { players, error, load } = getPlayers() //request endpoint
load()
watchEffect(() => {
console.log('watch effect function')
})
return { players, error }
}
}
</script>
Upvotes: 2
Views: 6763
Reputation: 9344
This is an example using the latest syntax with <script setup>
and computed()
<template>
<img v-if="loading" :src="your/path.gif" />
</template>
<script setup>
import { computed, onMounted, ref } from 'vue';
const data = ref();
const loading = computed(() => data.value? true : false);
onMounted(() => {
try{
const resp = await fetch('your-api/url')
data.value = resp;
}
catch (error){
console.log(error);
}
})
</script>
Similar to normal refs, you can access the computed result as loading.value
. Computed refs are also auto-unwrapped in templates so you can reference them without .value
in template expressions.
A computed property automatically tracks its reactive dependencies. Vue is aware that the computation of loading
depends on data
, so it will update any bindings that depend on loading
when data
changes.
In case you are having issues with the gif not been loaded from the start of the animation each time, check this here.
Upvotes: 0
Reputation: 2997
Vue apps should be data-driven. So, instead of relying on effects, change how your app looks by setting your data. If you're fetching some data from an endpoint, it's safe to assume you'll be putting it somewhere to display it in your app, like a Ref
.
So, why not display your loading spinner as long as your Ref
is not the data it is waiting to become? i.e., display a GIF while someRef == null
?
<template>
<img v-if="data === null" src="./img/loading.gif" alt="Loading" />
<div v-else>
<div>Here's the data!</div>
<pre>{{ data.toString() }}</pre>
</div>
</template>
<script>
import { ref, onMounted } from 'vue';
export default {
setup() {
const data = ref(null);
onMounted(() => {
// Replace this `fetch` call with whatever your endpoint call may be.
fetch('./endpoint')
.then(resp => resp.json())
.then(json => data.value = json);
});
return { data };
}
};
</script>
Does that make sense? Your app should be modelling your data. You can take advantage of the fact that "a loading GIF should only be displayed while we do not have the data" to, well... display a GIF as long as the data is unset.
Upvotes: 8