PlayerListComponent.vue 5.6 KB
<template>
  <!-- 内容区域 -->
  <div class="grid-container" style="width: 100%;height: 100%;display: flex;flex-wrap: wrap;">
    <div v-for="(item, i) in items"
         :key="i"
         class="grid-item"
         :style="item.gridStyle"
         @click="playerClick(item, i, items.length)"
         @mouseenter="handleMouseEnter(item, i)"
         @mouseleave="handleMouseLeave(item, i)">
      <video-player :class="`video${i}`" ref="player"
                    :initial-play-url="videoUrl[i]"
                    style="width: 100%;height: 100%; border: 1px black"
                    @click="playerClick(item, i, items.length)"
                    @play-error="handlePlayError(i)"
      ></video-player>
    </div>
  </div>
</template>
<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等),
//例如:import 《组件名称》 from '《组件路径》,
import VideoPlayer from './JessVideoPlayer.vue'

export default {
  //import引入的组件需要注入到对象中才能使用"
  components: { VideoPlayer },
  props: {
    value: {
      type: Number,
      default: 9
    },
    videoUrl: {
      type: Array,
      default: []
    }
  },
  data() {
    //这里存放数据"
    return {
      items: [],
      selectedPlayerIndex: -1 // 用于跟踪当前选中的播放器索引
    }
  },
  //计算属性 类似于data概念",
  computed: {
  },
  //监控data中的数据变化",
  watch: {
    /**
     * 监听value值变化
     * @param val
     */
    value(val) {
      this.updateGridTemplate(val)
    },
    /**
     * 监听videoUrl变化
     * @param newVal
     */
    videoUrl: {
      handler(newVal) {
        console.log('videoUrl changed:', newVal);
        // 如果需要,可以在这里进行额外的处理
      },
      deep: true
    }
  },
  //方法集合",
  methods: {
    /**
     * 循环赋值 items 并且返回items
     */
    setItems(num, gridStyle) {
      let items = []
      for (let i = 0; i < num; i++) {
        items.push({ name: `Item ${Number(i) + 1}`, gridStyle: gridStyle })
      }
      this.items = items
    },
    /**
     * 改变播放窗口数量
     */
    updateGridTemplate(val) {
      let gridStyle = {}
      switch (val) {
        case 1:
          gridStyle = { width: '99.5%', height: '99.5%' }
          break
        case 4:
          gridStyle = { width: '49.5%', height: '49.5%' }
          break
        case 9:
          gridStyle = { width: '33%', height: '33%' }
          break
        case 16:
          gridStyle = { width: '24.5%', height: '24.5%' }
          break
        default:
          this.$message.error("服务错误,请联系管理员")
          console.log(`updateGridTemplate 方法参数错误 val: ${val}`)
          return
      }
      this.setItems(Number(val), gridStyle)
    },
    /**
     * 播放窗口点击事件
     */
    playerClick(data, index, len){
      this.updateGridTemplate(len)
      this.selectedPlayerIndex = index
      const newGridStyle = { ...data.gridStyle, border: '1px solid red' }
      this.$set(this.items, index, { ...data, gridStyle: newGridStyle })
      this.$emit('playerClick', data, index, len);
    },
    /**
     * 鼠标悬停事件处理
     */
    handleMouseEnter(data, index) {
      if (this.selectedPlayerIndex !== index) {
        const newGridStyle = { ...data.gridStyle, border: '1px solid #36a3f7' } // 悬停时边框颜色变为蓝色
        this.$set(this.items, index, { ...data, gridStyle: newGridStyle })
      }
    },
    /**
     * 鼠标离开事件处理
     */
    handleMouseLeave(data, index) {
      if (this.selectedPlayerIndex !== index) {
        const newGridStyle = { ...data.gridStyle, border: '1px solid black' } // 离开时边框颜色恢复为黑色
        this.$set(this.items, index, { ...data, gridStyle: newGridStyle })
      }
    },
    destroy(idx) {
      this.clear(idx.substring(idx.length - 1))
    },
    setPlayUrl(url, idx) {
      // 使用Vue的$set方法来确保数组的变化能够被Vue检测到
      this.$set(this.videoUrl, idx, url)
      let _this = this
      setTimeout(() => {
        window.localStorage.setItem('videoUrl', JSON.stringify(_this.videoUrl))
      }, 100)
    },
    /**
     * 处理播放错误事件
     * @param index 当前播放器的索引
     */
    handlePlayError(index) {
      console.log(`播放失败,尝试播放下一个视频地址,索引: ${index}`);
      // 尝试播放下一个视频地址
      if (index < this.videoUrl.length - 1) {
        this.setPlayUrl(this.videoUrl[index + 1], index + 1);
      } else {
        console.log('所有视频地址均播放失败');
        // 可以在这里添加其他处理逻辑,例如显示错误信息
      }
    }
  },
  //生命周期 - 创建完成(可以访问当前this实例)",
  created() {
  },
  //生命周期 - 挂载完成(可以访问DOM元素)",
  mounted() {
    this.updateGridTemplate(this.value)
  },
  beforeCreate() {
  }, //生命周期 - 创建之前",
  beforeMount() {
  }, //生命周期 - 挂载之前",
  beforeUpdate() {
  }, //生命周期 - 更新之前",
  updated() {
  }, //生命周期 - 更新之后",
  beforeDestroy() {
  }, //生命周期 - 销毁之前",
  destroyed() {
  }, //生命周期 - 销毁完成",
  activated() {
  } //如果页面有keep-alive缓存功能,这个函数会触发",
}
</script>
<style scoped>
.video {
  width: 100%;
  height: 100%;
}
.play-list-component {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
}
.grid-container {
  gap: 1px; /* 子元素之间的间距 */
}

.grid-item {
  background-color: black;
  text-align: center;
}
</style>