绿满眶商城微信小程序-uniapp
zxl
2025-06-24 e50f021ddf73b80f5a1273b8b01e7dd4344a4cdc
pages/tabbar/index/home.vue
@@ -4,17 +4,23 @@
    <swiper 
      class="video-swiper" 
      vertical 
      circular
      :current="currentIndex"
      @change="onSwiperChange"
     easing-function="linear"
    >
      <swiper-item v-for="(item, index) in videoList" :key="item.id">
      <swiper-item
      v-for="(item, index) in videoList"
      :key="item.id"
      @touchstart="handleSwiperStart"
      @touchmove="handleSwiperMove"
      @touchend="handleSwiperEnd(item)"
       >
      <view style="width: 100%;height: 100%;" v-if="item.videoContentType === 'video'">
           <!-- 播放按钮(仅当视频暂停时显示) -->
           <view 
            class="play-icon" 
            @click="togglePlay(index)"
            v-if="!currentVideoIsPlaying"
            v-show="!currentVideoIsPlaying"
           >
            <image src="/static/video/play.png" style="width: 45px;height: 45px" mode="aspectFit"></image>
           </view>
@@ -22,7 +28,7 @@
            :id="'video'+index"
            :ref="'video'+index"
            :src="item.videoUrl"
            :autoplay="currentIndex === index"
            :autoplay="false"
            :controls="false"
            :loop="true"
            :object-fit="item.objectFit"
@@ -34,7 +40,6 @@
            @click="togglePlay(index)"
            @timeupdate="onTimeUpdate($event)"
            @loadedmetadata="onLoadedMetadata($event)"
           ></video>
           <!-- 自定义控制条 -->
           <view 
@@ -298,14 +303,20 @@
      isFullScreen: false,
      windowHeight: 0,
      currentIndex: 0, // 当前播放的视频索引
      videoList: [
      ],   // 视频列表数据
      videoList: [],   // 视频列表数据
      videoContexts: [], // 视频上下文对象集合
      videoBufferOffset: 0.1 ,// 视频预加载参数
      videoLiveOffset: 5, // 保留当前视频前后各多少个视频上下文
      touchXY: {  // 监听左滑右滑
         startX: 0,
         endX: 0,
         startY: 0,
         endY: 0
      },
      loading: false,  // 是否正在加载
      videoQuery: {
         pageNumber: 1,
         pageSize: 6,
         pageSize: 10,
         videoFrom: 'recommend'
      }
    }
@@ -342,10 +353,6 @@
     } else { 
      this.loadVideos();
     }
  },
  onReady() {
    // 初始化视频上下文
    this.initVideoContexts();
  },
  onShareAppMessage(e) {
   const userInfo = storage.getUserInfo();
@@ -657,10 +664,53 @@
     },
    // 初始化视频上下文
    initVideoContexts() {
      this.videoContexts = this.videoList.map((_, index) => {
        let videoContent = uni.createVideoContext(`video${index}`, this);
        return videoContent;
      });
     const start = Math.max(0, this.currentIndex - this.videoLiveOffset);
     const end = Math.min(this.currentIndex + this.videoLiveOffset, this.videoList.length - 1);
     let contextsLength = this.videoContexts.length;
     if (contextsLength === 0) {
        // 第一次初始化
        for (let i = 0; i < this.videoList.length; i++) {
         if (i < start || i > end) {
            this.videoContexts.push(null)
         } else {
            let videoContent = uni.createVideoContext(`video${i}`, this);
            videoContent.seek(this.videoBufferOffset);
            videoContent.pause();
            this.videoContexts.push(videoContent);
         }
        }
     } else {
       for (let i = 0; i < this.videoList.length; i++) {
          contextsLength = this.videoContexts.length
         if (contextsLength - 1 >= i) {
            // 如果已经是null了就不用管,因为视频加载只会在后面push,前面已经设置为null则无需处理
            if (this.videoContexts[i] == null) {
               continue
            }
            // 超出可视化范围的视频直接释放资源,并置为null
            if (i < start || i > end) {
               if (this.videoContexts[i]) {
                  this.videoContexts[i].stop();
                  this.videoContexts[i] = null
               }
            }
         } else {
            if (i < start || i > end) {
               this.videoContexts.push(null);
            } else {
               let videoContent = uni.createVideoContext(`video${i}`, this);
               videoContent.seek(this.videoBufferOffset);
               videoContent.pause();
               this.videoContexts.push(videoContent);
            }
         }
       }
     }
     // 将当前视频设置为播放
     if (this.videoContexts[this.currentIndex]) {
        this.videoContexts[this.currentIndex].play()
     }
    },
    
    // 加载视频数据
@@ -713,13 +763,78 @@
      }
      
      this.startPauseTime = 0;
      // 设置当前播放视频的总时长
      this.duration = this.videoList[this.currentIndex].videoDuration;
      this.formartDuration = this.sliderFormatTime(this.duration);
      // 播放当前视频
      if (this.videoContexts[this.currentIndex]) {
         this.videoContexts[this.currentIndex].play();
      }
      // 设置当前播放视频的总时长
      this.duration = this.videoList[this.currentIndex].videoDuration;
      this.formartDuration = this.sliderFormatTime(this.duration);
      this.clearVideoContext()
    },
   // 清除超出视频可视化区域的视频上下文
    async clearVideoContext() {
      // 对超出可视化区域的视频上下文做销毁处理
      const start = Math.max(0, this.currentIndex - this.videoLiveOffset);
      const end = Math.min(this.currentIndex + this.videoLiveOffset, this.videoList.length - 1);
      for (let i = 0; i < this.videoContexts.length; i++) {
         if (i < start || i > end) {
            if (this.videoContexts[i]) {
               this.videoContexts[i].stop();
               this.videoContexts[i] = null
            }
         } else {
            if (this.videoContexts[i] == null) {
               let videoContent = uni.createVideoContext(`video${i}`, this);
               videoContent.seek(this.videoBufferOffset);
               videoContent.pause();
               this.videoContexts[i] = videoContent;
            }
         }
      }
      // 如果剩余视频不足,触发请求获取更多视频
      if (this.videoList.length - 1 < this.currentIndex + this.videoLiveOffset) {
         this.loadVideos()
      }
   },
   // 开始触摸
   handleSwiperStart(e) {
      console.log("开始触摸", e);
       this.touchXY.startX = e.touches[0].pageX
       this.touchXY.startY = e.touches[0].pageY
   },
   // 触摸中
   handleSwiperMove(e) {
      console.log("触摸中", e);
       this.touchXY.endX = e.touches[0].pageX
       this.touchXY.endY = e.touches[0].pageY
   },
   // 结束触摸
   handleSwiperEnd(item) {
       const diffX = this.touchXY.endX - this.touchXY.startX
       const diffY = this.touchXY.endY - this.touchXY.startY
       // 判断是否是横向滑动(X轴变化大于Y轴变化)
       if (Math.abs(diffX) > Math.abs(diffY)) {
         if (diffX > 0) {
           console.log('右滑')
         if (item.goodsList && item.goodsList.length > 0) {
            this.jumpToPay(item.id)
         }
         } else {
           console.log('左滑')
         }
       }
       // 重置坐标
       this.touchXY = {
         startX: 0,
         endX: 0,
         startY: 0,
         endY: 0
      }
    },
    
    // 收藏/取消收藏