Vue JS - 使用 v-for 播放/暂停的视频处理

问题描述

我使用请求接受视频链接,然后使用 v-for 我显示它们问题是播放按钮仅适用于一个视频,而不适用于所有视频,我希望播放适用于每个视频也暂停这里是我的代码

<video
  width="206"
  height="126"
  :src="c.video"
  @playing="updatePaused"
  @pause="updatePaused"
  @canplay="updatePaused"
></video>

  <span v-show="paused" @click="play" class="play_btn1"
    ><i class="uil uil-play"></i
  ></span>
  <span
    v-show="playing"
    @click="pause"
    class="play_btn1"
    ><i class="uil uil-pause"></i
  ></span>

脚本

<script>
export default {
  computed: {
    playing() {
      return !this.paused;
    },},methods: {
    updatePaused(e) {
      this.videoElement = e.target;
      this.paused = e.target.paused;
    },play() {
      this.videoElement.play();
    },pause() {
      this.videoElement.pause();
    },data() {
    return {
      videoElement: null,}
  },};
</script>

解决方法

您可以使用 ref 访问 HTML 元素。只需将 ref 与循环内的任何名称绑定,您就可以使用 this.$refs[<name>] 访问该元素。

现在因为 ref 在一个循环中,所以你必须使用 this.$refs[<name>][<loopIndex>] 来访问它。

在此处了解有关参考的更多信息:https://vuejs.org/v2/guide/components-edge-cases.html#Accessing-Child-Component-Instances-amp-Child-Elements

new Vue({
  el: "#app",data() {
    return {
      videosState: {},videos: [
        {
          id: 1,url:
            "https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4"
        },{
          id: 2,url:
            "https://sample-videos.com/video123/mp4/240/big_buck_bunny_240p_10mb.mp4"
        }
      ]
    };
  },methods: {
    changeVideoState(idx) {
      // Create initial state for the video if it
      // it doesn't exist
      if (!this.videosState[idx]) {
        /**
          When you add a new field to
          an object that doesn't exist 
          yet(in the object),vue doesn't 
          know about the changes. So `this.$set`
          notifies vue about the change
          so that vue can update the
          dom correctly.
        */
        this.$set(this.videosState,idx,{
          play: false
        })
      }

      const isPlaying = this.videosState[idx].play;
      const video = this.$refs.video[idx];

      if (!isPlaying) {
        video.play();
      } else {
        video.pause();
      }

      this.videosState[idx].play = !isPlaying
    }
  }
});
<div id="app">
  <div
    v-for="(video,idx) in videos"
    :key="video.id"
    style="
      display: inline-flex;
      flex-direction: column;
      margin-bottom: 1rem;
    "
  >
    <video ref="video" :src="video.url" width="400"></video>
    <button @click="changeVideoState(idx)">
      {{ videosState[idx] && videosState[idx].play ? "Pause" : "Play" }}
    </button>
  </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script>

注意:如果您想在加载/创建组件时访问 refs,您必须在 mounted 生命周期中执行此操作:

new Vue({
    mounted() {
        // Access refs here
    }
})

Refs 仅在组件完全渲染后可用。