Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

martinbean's avatar

Calling methods on template ref in Vue 3 component not working

I’m trying to programatically control a video in a Vue 3 (with TypeScript and Composition API) component. I have a <video> element and some code that looks like this:

<template>
    <div>
        <video ref="videoElement">
            <slot name="sources" />
        </video>
        <div>
            <button v-if="playing" @click="pause">Pause</button>
            <button v-else @click="play">Play</button>
        </div>
    </div>
</template>

<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
    setup() {
        const videoElement = ref<InstanceType<typeof HTMLVideoElement>>();
        const pause = () => videoElement.value!.pause();
        const play = () => videoElement.value!.play();
        const playing = ref(false);

        videoElement.value!.addEventListener('pause', () => playing.value = false);
        videoElement.value!.addEventListener('play', () => playing.value = true);

        return {
            pause,
            play,
            playing,
            videoElement,
        };
    },
});
</script>

However, when clicking the “play” button. Nothing happens, but nothing is logged to the console either.

If I log the videoElement value, it correctly reports that it is a HTMLVideoElement instance, but calling play() on that instance doesn’t actually play the video.

Can any one see where I might be going wrong?

0 likes
4 replies
martinbean's avatar

@jlrdw It doesn’t do anything because videoElement is not a HTML video element; it’s a Vue template ref.

apex1's avatar

@martinbean Just played around with your code, and this was working. Video plays when you hit play, button changes to pause, and vice versa. Unless there's something I'm missing with your use case?

export default defineComponent({
  setup() {
    const videoElement = ref<InstanceType<typeof HTMLVideoElement>>();
    const playing = ref(false);
    const pause = () => {
      playing.value = false;
      videoElement.value?.pause();
    }
    const play = () => {
      playing.value = true;
      videoElement.value?.play();
    }

    return {
      pause,
      play,
      playing,
      videoElement,
    };
  }
});
apex1's avatar

You have videoElement but your ref in your video element is videoPlayer.

Please or to participate in this conversation.