当前位置:首页 > VUE

vue实现视频下滑

2026-01-16 03:30:02VUE

Vue 实现视频下滑功能

实现视频下滑功能通常涉及监听滚动事件、动态加载视频内容以及优化性能。以下是具体实现方法:

vue实现视频下滑

监听滚动事件

在 Vue 中可以通过 @scroll 事件监听滚动行为,结合 scrollTopclientHeight 判断是否到达底部。

vue实现视频下滑

<template>
  <div class="video-container" @scroll="handleScroll">
    <div v-for="(video, index) in videos" :key="index">
      <video :src="video.src" controls></video>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      videos: [],
      currentPage: 1,
      isLoading: false
    };
  },
  methods: {
    handleScroll(event) {
      const container = event.target;
      const scrollBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
      if (scrollBottom < 100 && !this.isLoading) {
        this.loadMoreVideos();
      }
    },
    loadMoreVideos() {
      this.isLoading = true;
      // 模拟异步加载
      setTimeout(() => {
        const newVideos = [...Array(5)].map((_, i) => ({
          src: `https://example.com/video${this.currentPage + i}.mp4`
        }));
        this.videos = [...this.videos, ...newVideos];
        this.currentPage += 5;
        this.isLoading = false;
      }, 1000);
    }
  },
  mounted() {
    this.loadMoreVideos();
  }
};
</script>

<style>
.video-container {
  height: 100vh;
  overflow-y: auto;
}
video {
  width: 100%;
  margin-bottom: 20px;
}
</style>

使用 Intersection Observer API

Intersection Observer 更高效,适合监听元素是否进入视口。

<template>
  <div class="video-container">
    <div v-for="(video, index) in videos" :key="index" ref="videoItems">
      <video :src="video.src" controls></video>
    </div>
    <div ref="loader" v-if="isLoading">Loading...</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      videos: [],
      currentPage: 1,
      isLoading: false,
      observer: null
    };
  },
  methods: {
    initObserver() {
      this.observer = new IntersectionObserver((entries) => {
        if (entries[0].isIntersecting && !this.isLoading) {
          this.loadMoreVideos();
        }
      }, { threshold: 0.1 });
      this.observer.observe(this.$refs.loader);
    },
    loadMoreVideos() {
      this.isLoading = true;
      setTimeout(() => {
        const newVideos = [...Array(5)].map((_, i) => ({
          src: `https://example.com/video${this.currentPage + i}.mp4`
        }));
        this.videos = [...this.videos, ...newVideos];
        this.currentPage += 5;
        this.isLoading = false;
      }, 1000);
    }
  },
  mounted() {
    this.loadMoreVideos();
    this.$nextTick(() => {
      this.initObserver();
    });
  },
  beforeDestroy() {
    if (this.observer) {
      this.observer.disconnect();
    }
  }
};
</script>

优化性能

  • 懒加载视频:使用 loading="lazy" 属性或动态设置 src
  • 虚拟滚动:对于大量视频,使用 vue-virtual-scroller 等库减少 DOM 数量。
  • 节流滚动事件:避免频繁触发加载逻辑。
import { throttle } from 'lodash';

export default {
  methods: {
    handleScroll: throttle(function(event) {
      const container = event.target;
      const scrollBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
      if (scrollBottom < 100 && !this.isLoading) {
        this.loadMoreVideos();
      }
    }, 200)
  }
};

完整示例代码

结合上述方法,以下是一个完整的实现:

<template>
  <div class="video-container" @scroll="handleScroll">
    <div v-for="(video, index) in videos" :key="index">
      <video :src="video.src" controls :poster="video.poster"></video>
    </div>
    <div v-if="isLoading" class="loading">Loading more videos...</div>
  </div>
</template>

<script>
import { throttle } from 'lodash';

export default {
  data() {
    return {
      videos: [],
      currentPage: 1,
      isLoading: false,
      hasMore: true
    };
  },
  methods: {
    handleScroll: throttle(function(event) {
      const container = event.target;
      const scrollBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
      if (scrollBottom < 100 && !this.isLoading && this.hasMore) {
        this.loadMoreVideos();
      }
    }, 200),
    async loadMoreVideos() {
      this.isLoading = true;
      try {
        const newVideos = await this.fetchVideos(this.currentPage);
        if (newVideos.length === 0) {
          this.hasMore = false;
        } else {
          this.videos = [...this.videos, ...newVideos];
          this.currentPage += 1;
        }
      } catch (error) {
        console.error('Failed to load videos:', error);
      } finally {
        this.isLoading = false;
      }
    },
    fetchVideos(page) {
      return new Promise((resolve) => {
        setTimeout(() => {
          resolve(
            [...Array(5)].map((_, i) => ({
              src: `https://example.com/video${page + i}.mp4`,
              poster: `https://example.com/thumbnail${page + i}.jpg`
            }))
          );
        }, 1000);
      });
    }
  },
  mounted() {
    this.loadMoreVideos();
  }
};
</script>

<style>
.video-container {
  height: 100vh;
  overflow-y: auto;
}
video {
  width: 100%;
  margin-bottom: 20px;
}
.loading {
  text-align: center;
  padding: 10px;
}
</style>

标签: 视频vue
分享给朋友:

相关文章

vue实现aop切面

vue实现aop切面

Vue 实现 AOP 切面编程的方法 在 Vue 中实现 AOP(面向切面编程)可以通过多种方式,以下是几种常见的实现方法: 使用 Vue 混入(Mixins) Vue 的混入机制可以用于实现横切关…

vue实现添加用户

vue实现添加用户

Vue 实现添加用户功能 数据绑定与表单设计 在 Vue 中实现添加用户功能,首先需要设计一个表单,用于收集用户输入的数据。通过 v-model 实现双向数据绑定,确保表单数据与 Vue 实例中的数据…

vue如何实现冒泡

vue如何实现冒泡

Vue 实现冒泡排序 在 Vue 中实现冒泡排序,可以通过数据绑定和响应式特性动态展示排序过程。以下是一个完整的实现示例,包含代码和详细说明。 数据准备 在 Vue 的 data 中定义一个数组作…

vue实现好友列表

vue实现好友列表

实现好友列表的Vue组件 数据准备 在Vue组件的data中定义好友列表数据,通常是一个数组对象,每个对象包含好友的基本信息如ID、头像、昵称等。 data() { return {…

vue前端实现打印功能

vue前端实现打印功能

使用Vue实现前端打印功能 在Vue项目中实现打印功能可以通过多种方式完成,以下是几种常见的方法: 使用window.print()方法 这是最简单的打印方式,直接调用浏览器的打印功能。 me…

vue播放倍速怎么实现

vue播放倍速怎么实现

实现Vue播放倍速的方法 在Vue中实现播放倍速功能通常涉及HTML5的<video>元素或第三方播放器库。以下是几种常见实现方式: 使用原生HTML5 video元素 通过ref获取v…