I have an api endpoint that I built that returns a list of products and everything there is working just fine. I tried to use this github link to get a working example because the endpoint I am using is not publicly available.
In my case, lets say we could hit this fictional endpoint: https://api.github.com/orgs/vuejs/repos?id=123456
, one repo would be returned and what happens is it would appear immediately. How could we get the new items to fade in rather than immediately appearing on subsequent requests?
For the sake of this example, how could we make the repos fade in without actually wrapping the v-if
element and the v-else
element with <transition>
? There should be a transition when this.response = data
happens
const { createApp } = Vue
createApp({
data() {
return {
response: null,
loaded: false
}
},
methods: {
fetchData() {
fetch('https://api.github.com/orgs/vuejs/repos')
.then(response => response.json())
.then(data => {
this.response = data;
this.loaded = true;
})
}
},
mounted() {
this.fetchData();
},
}).mount('.repo-wrapper')
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.fade-enter-to,
.fade-leave-from {
opacity: 1;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
<script src="https://unpkg.com/vue@3"></script>
<div >
<div v-if="!loaded" >LOADING...</div>
<div v-else>
<transition-group name="fade">
<div v-for="(repo, index) in response" :key="repo.id">
<a :href="repo.html_url" :title="repo.description" target="_blank">
{{ repo.name }}
</a>
</div>
</transition-group>
</div>
</div>
CodePudding user response:
Problem is transition-group
is applying transitions to individual items of already rendered list. When you fetch your data, the list is not rendered at all as it is hidden after v-else
and when it shows for the first time, that does not count as list change
See example below with changes:
response
initial value is[]
instead of nullv-for
is rendered no matter if data is loaded or not
It works!
const { createApp } = Vue
createApp({
data() {
return {
response: [],
}
},
methods: {
fetchRandom() {
this.fetchData(Math.floor(Math.random() * 20))
},
fetchData(pageSize = 10) {
fetch(`https://api.github.com/orgs/vuejs/repos?per_page=${pageSize}`)
.then(response => response.json())
.then(data => {
this.response = data;
})
}
},
mounted() {
this.fetchData();
},
}).mount('.repo-wrapper')
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
.fade-enter-to,
.fade-leave-from {
opacity: 1;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 1s ease;
}
<script src="https://unpkg.com/vue@3"></script>
<div >
<button @click="fetchRandom">Reload</button>
<ul>
<transition-group name="fade">
<li v-for="(repo, index) in response" :key="repo.id">
<a :href="repo.html_url" :title="repo.description" target="_blank">
{{ repo.name }}
</a>
</li>
</transition-group>
</ul>
</div>