surmon-china / videojs-player

@videojs player component for @vuejs(3) and React.
https://github.surmon.me/videojs-player
MIT License
5.25k stars 1.13k forks source link

v-for循环中options使用函数返回,当外层包裹div有点击事件 会重复触发options的绑定函数 #366

Open hugselina2019 opened 4 years ago

hugselina2019 commented 4 years ago

1、描述 v-for循环多个video , 每个video的options使用函数返回 代码如下 截图如下(真的不太会用github的格式化代码,咋格式,咋高亮,, 有木有教程呀) template代码:

<div class="video-wrap">
      <div 
        style="width: 320px; height: 160px; margin-left: 15px; background-color: #f5f5f5;"
        :class="[itemActive == idx ? 'active' : '']"
        v-for="(item, idx) of videoData"
        :key="item.id"
        @click="handleItemClick(idx)">
        <video-player class="vjs-custom-skin sel-video" :options="playerOption(item.url)" v-if="item.hasVideo"></video-player>
      </div>
    </div>

script相关代码:

// require styles
import 'video.js/dist/video-js.css'
import 'vue-video-player/src/custom-theme.css'
// video-player
import { videoPlayer } from 'vue-video-player'
// rtmp video-flash
import 'videojs-flash'
export default {
  name: 'video-sel',
  data () {
    return {
      video: 'hello video',
      playerOptions: {
        // height: '260',
        language: 'en',
        playbackRates: [0.5, 1.0, 1.5, 2.0],
        sources: [{
          type: "rtmp/mp4",
          src: "rtmp://58.200.131.2:1935/livetv/cctv1"
        }],
        techOrder: ['flash'],
        autoplay: false,
        controls: true,
        poster: "../../assets/images/video2.jpg",
        notSupportedMessage: '不支持的视频格式'
      },
      videoData: [
        {
          id: '1001',
          url: 'rtmp://58.200.131.2:1935/livetv/cctv1',
          hasVideo: true
        },
        {
          id: '1002',
          url: 'rtmp://58.200.131.2:1935/livetv/cctv1',
          hasVideo: true
        },
        {id: '1003',}, {id: '1004',}
      ],
      itemActive: 0
    }
  },
  components: {
    videoPlayer
  },
methods: {
    playerOption (url) {
      console.log('player options:', url)
      const playerOptions = {
        // height: '260',
        language: 'en',
        playbackRates: [0.5, 1.0, 1.5, 2.0],
        sources: [{
          type: "rtmp/mp4",
          src: url
        }],
        techOrder: ['flash'],
        autoplay: false,
        controls: true,
        poster: "../../assets/images/video2.jpg",
        notSupportedMessage: '不支持的视频格式'
      }
      return playerOptions
    },
    handleItemClick (idx) {
      let val = this.itemActive
      if (val == idx) {
        this.itemActive = -1
        return;
      } else {
        this.itemActive = idx
      }
    }
  }

css部分: image

2、复现 上面截图 我在playerOption函数中打印了传入的url , 可以看到 当前页面有2个已渲染的video , 每次点击空白 都会触发2次playerOption函数 导致2个已渲染的video重新渲染 如下图 (这里切换使用了vue 的obj写法、在上层覆盖透明div 将click事件与选中样式分层 这些方法都不可以,只要我改变了itemActive 无论选中样式在哪里 ,都会重新触发playerOption函数) image

3、期望 因为目前项目需求 开始这些video都是不渲染的 点击某一位置 在该位置渲染video 所以需要一个选中效果,这块目测应该是个bug ?  希望可以点击空白不重新触发playerOption函数

hugselina2019 commented 4 years ago

看来各位老哥都没有我这边的奇葩需求 /捂脸, 不过这确实有问题 不仅是改变itemActive 会导致触发options绑定函数, 改变data中的任一数据都会触发 /捂脸

sukeqin commented 4 years ago

我遇到你一样的问题,请问你解决了吗? @hugselina2019

hugselina2019 commented 4 years ago

暂时解决了 使用iframe + v-if , 由于iframe的沙盒机制 它的url传递不进去进而达到预期效果, 但是很不理想

hzfvictory commented 2 years ago

我用的 v-once 解决的,稳定性比较高