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

video-player 中options 使用函数, 点击外层包裹div 触发了options的绑定函数, option不使用函数不会触发此bug #365

Closed hugselina2019 closed 4 years ago

hugselina2019 commented 4 years ago

中文用户注意:

  1. 尽量用英文描述你的 issue
  2. 不要把内容堆彻在标题上,逻辑清晰地写在内容区
  3. 贴代码要提前格式化好,有颜色高亮那种,贴文本,不要贴图片
  4. 提问题前,必须仔细阅读 REMADE.md + 在已关闭的问题中寻找与自身相关的问题,90% 的可能它已经被解决
  5. 如果无法做到提一个合格、优秀的问题,则问题会被 close + block

1、场景描述: vue-cli中外层div拥有点击事件 而且加了修饰符 @click.stop = "handleItemClick" 内层是video-player子组件,autoplay: true, options是一个函数(:options="getPlayerOption(item.rtmpurl)") , 外层item是v-for的一个dataArr 每选中一次根据index实现了一个选中高亮效果 2、页面逻辑简介 左侧是一个tree 使用andv的a-tree, 右侧为video放置 点击tree的一个子项 生成videoData 并渲染 3、bug描述: 每当我点击外层的item触发handleItemClick时 同步会触发内层options的绑定函数 getPlayerOption,从而导致url重新赋值 (即使url不曾改变,比如第一个位置的url为abc.m3u8 / 第二次依然传入的是abc.m3u8) 导致video-player重新渲染,这听起来很不可思议 , 但事实如此 我在代码中尝试了各种click的修饰符,以及class样式的绑定(obj模式/arr模式),以及将点击事件分离 内部加一个透明的高层遮罩。这些方法都没有效果 , 这个问题再options不使用函数时不会发生 求解 4、部分代码展示 template部分1: `<div :class="['video-item2', itemActiveIndex == idx ? 'item-active' : '', 'vjs-custom-skin']" v-for="(item, idx) of videoData2" :key="idx" @click="handleitemActive(idx)">

        <div class="css-tool" @click.stop="handleFullScreen" v-if="item.isRtsp">
          <img src="../../static/img/full.png" alt="full-img" class="cssimg">
        </div>
      </div>`

template部分2(事件分离 高层遮罩 更换class的obj绑定): `<div class="video-item vjs-custom-skin" :class="{ 'item-active': itemActiveIndex == idx }" v-for="(item, idx) of videoData" :key="idx"> <div class="hover-click" @click.stop="handleitemActive(idx)">

        <div class="css-tool" @click.stop="handleFullScreen" v-if="item.isRtsp">
          <img src="../../static/img/full.png" alt="full-img" class="cssimg">
        </div>
      </div>`

data部分: data () { return { spinning: true, treeData: [], replaceFields: { key: 'id' }, btnActive: 1, // 当前默认选中按钮组 1 => 2 x 2 ; 2 = > 3 x 3 ; 3 => 4 x 4 btnActiveIndex: 0, // 当前所需要添加数据的 数组索引 itemActiveIndex: 0, // 当前选中的video dom index ; -1 表示未选中 videoData: [{}, {}, {}, {}], // 很重要 selectVideoDom: false, // 是否选择了 video dom treeSelectData: {}, // tree select data channel: '1', // 通道 本地取流(rtsp)还是总公司取流(rtmp) 默认1 本地 PlayerOption: { 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', 'html5'], autoplay: true, muted: true, controls: true, fluid: true, poster: "../../assets/images/video.png", notSupportedMessage: '不支持的视频格式' } } }, 事件部分: handleitemActive : handleitemActive (idx) { // video dom active console.log('video dom change index:', idx) let that = this if (that.itemActiveIndex == idx) { that.itemActiveIndex = -1 that.selectVideoDom = false } else { that.itemActiveIndex = idx that.selectVideoDom = true } },

getPlayerOption: getPlayerOption (url) { console.log('get player option url:', url) console.log('get player option ?video-data:', this.videoData) const playerOptions = { language: 'en', playbackRates: [0.5, 1.0, 1.5, 2.0], sources: [{ type: "rtmp/mp4", src: url, // v-for传过来的 后台获取的url 或者使用下面写死 依然会重新渲染 // src: 'rtmp://58.200.131.2:1935/livetv/cctv1' }], techOrder: ['flash', 'html5'], autoplay: true, muted: true, controls: true, fluid: true, poster: "../../assets/images/video.png", notSupportedMessage: '不支持的视频格式' } return playerOptions }

handleFullScreen: // 这并不重要

handleFullScreen () { console.log('full screen click:', this.treeSelectData) // this.$message.success('点击了悬浮栏') let tdata = this.treeSelectData localStorage.setItem('homeUrl', tdata.rtmpurl) localStorage.setItem('homeIndexCode', tdata.value) var url = 'static/homevideo-rtmp.html' window.open(url, '_blank') },

hugselina2019 commented 4 years ago

使用insert code 这种也不会高亮格式化~ 方 需要的话可以邮件提供vue单页

hugselina2019 commented 4 years ago

经过一下午的测试发现 如果option不使用函数 表现形式正常, 或者删掉:class中的三元判断 表现形式正常