uni-app怎样实现类似抖音的上下滑动短视频切换

作者:袖梨 2026-07-13
最可行起点是swiper+vertical="true",但需严格管控video生命周期:@change中用$nextTick触发play()、动态列表重置currentIndex、iOS/微信端设muted=true并监听loadedmetadata再尝试开声、仅保留3个video实例防内存爆炸、小程序用cover-view抢touch事件。

直接用 swiper + vertical="true" 是最可行的起点,但真机上卡顿、黑屏、自动播放失败,90% 都是因为没控制好 video 实例的生命周期和平台行为差异。

为什么 swiper @change 不能直接用来触发 play()

它不是实时滚动回调,而是分页对齐完成信号——滑动还没停稳,DOM 可能都还没渲染出来。iOS 上 current 更新还有微小延迟,拿它算进度或同步动画会错位。

  • 所有播放/暂停逻辑必须写在 @change 回调里,而不是 @touchmove@transition
  • 要在 onSwiperChange 中包一层 this.$nextTick,否则 this.$refs.video 可能为 undefined
  • 视频列表动态追加后,必须手动重置 currentIndex,否则容易越界或卡死在空白页

video 标签怎么写才能跨端自动播

iOS Safari 和微信 WebView 对带声视频的 autoplay 有硬性限制:没用户手势前,autoplay="true" + muted="false" 必然失败,表现就是“有声无画”或纯黑屏。

  • 首屏视频必须设 :muted="true" + :autoplay="true",让画面先出
  • 监听 @loadedmetadata@canplay,再调 videoContext.mute(false) 尝试开声(部分机型仍需用户点一下)
  • H5 端必须同时加 playsinlinewebkit-playsinlinex5-playsinline,否则 iOS 微信强制全屏
  • 小程序端禁用 autoplay,等 @loadedmetadata 触发后再 play(),避免并发加载阻塞主线程

怎么避免内存爆炸和滑动卡顿

一次性把 100 条视频都塞进 swiper-item,等于让浏览器同时解码 100 个首帧——iOS Safari 卡死,小程序白屏,App 端内存飙升到 500MB+。

  • 只保留 current - 1currentcurrent + 1 共 3 个 video 实例,其余用 v-if="false" 彻底移除 DOM
  • 每个 video 加 preload="metadata",而非 "auto";首次进入可视区才调 .load()
  • 滑出视口 500ms 后,执行 pause() + src = '' + load() 释放解码资源
  • 小程序里别用 scroll-viewvideo,它会截断原生手势;改用普通 view + transform: translateY 模拟滚动

小程序里 touchmove 为什么监听不到?

微信小程序的 video 是原生组件,层级高于所有 webview 内容,touchstart/move 事件根本无法穿透到它上面——这不是 bug,是设计。

  • 现象:手指一碰到视频区域,touchmove 就不触发,或只在边框空白处生效
  • 解法:用 cover-view 盖一层透明遮罩,把滑动事件抢过来,再手动控制 video 的显隐与 src 切换
  • 抖音小程序必须用 ref + this.$refs.video.play(),不能用 uni.createVideoContext
  • App 端必须用 nvue + 原生 video 组件,否则手势跟手、后台音频、低延迟都做不到

真正难的不是“怎么切”,而是「什么时候销毁、什么时候预加载、什么时候强制暂停」——这些边界点稍有偏差,用户划着划着就卡住或黑屏了。

相关文章

精彩推荐