I have a video component passing data from an async GET request to a child component:
// Inside a v-for loop
<video
:title="video.title"
:id="video._uid"
>
// ...
<Controls :videoData="video" />
When receiving the prop in Controls
I then use that data to select the video by it's id
in the DOM and set data properties according to that element:
created() {
setTimeout(() => {
this.video = document.getElementById(this.videoData._uid);
this.videoDuration = this.video.duration;
setInterval(() => {
this.videoCurrentTime = this.video.currentTime;
this.videoPlaying = !this.video.paused;
this.videoVolume = this.video.volume;
}, 1);
}, 1000);
}
The setTimeout
is to get around the data being asynchronous and the setInterval
is to continuously update the data, such as the current time of the video, whether it's paused or not, etc.
It works exactly as it should, but it seems really inefficient. What if someone has slow internet and it takes longer than 1000ms to fetch the data, for example.
I would think the fact it's in a v-for
loop would prevent the need for setTimeout
as the component wouldn't exist before the video has been fetched. I must be missing something.
Request:
created() {
this.fetchVersion().then(async () => {
await Axios.get(
`https://api.storyblok.com/v1/cdn/stories/videos?version=published&token=<STORYBLOK_TOKEN>&cv=${this.getVersion}`
).then(res => {
res.data.story.content.body.forEach(i => {
this.storyblokVideos.push(i);
});
});
});
}
Does anyone have a better way of making the data reactive?
UPDATE
Thanks to @potato's answer:
I set a data property called isLoading: true
then used the video's event oncanplay
to conditionally load the controls: @canplay="isLoading = false"
. No more async errors. Then I used the different events to pass data:
@play="playing = true"
@pause="playing = false"
@timeupdate="updateCurrentTime()"
@volumechange="updateVolume()"
Much more efficient.
1 Answer 1
Use events and callbacks to react to things as they happen instead of repeatedly checking for changes.
You can use the .then
function to do whatever needs to be done once the data is received.
You can learn about the <video>
element events here: https://www.w3schools.com/tags/ref_av_dom.asp
-
2\$\begingroup\$ Good spot! Can always rely on a potato. I'll update my question to reference your answer \$\endgroup\$Dan Knights– Dan Knights2020年07月05日 14:40:09 +00:00Commented Jul 5, 2020 at 14:40