uni-app中抖音式上下滑动需用swiper垂直分页切换,核心是:current双向绑定与@change回调控制播放逻辑,配合可视区渲染、ios静音策略适配及全屏兼容处理。

swiper vertical="true" 是起点,但 current + @change 才是控制核心
抖音式上下滑动不是滚动,而是分页切换。uni-app 的 swiper 组件天然适配这个逻辑,关键不是“怎么滑”,而是“谁在播、什么时候播”。:vertical="true" 必须设,:current="currentIndex" 必须双向绑定,所有播放/暂停动作都得写在 @change 回调里——它只在滑动完全停止、页面对齐后触发,不是实时滚动事件。
常见踩坑点:
- iOS 上
current更新有微小延迟,别拿它算进度条或做同步动画 - 安卓/H5 下
@change响应及时;iOS 微信 WebView 可能合并多次快速滑动,只触发一次 - 视频列表动态追加后,必须手动重置
currentIndex,否则容易越界或卡死在空白页 - 不要在
@change里直接调play(),先包一层this.$nextTick确保 DOM 就绪
video 播放失败?根本原因是 iOS 自动播放策略,不是代码写错了
iOS Safari 和微信 WebView 对带声音视频的自动播放限制极严:没有用户手势前,autoplay="true" + muted="false" 几乎必失败,表现就是“有声无画”或纯黑屏。这不是 bug,是系统级策略。
可行解法是顺应它:
- 首屏视频默认设
:autoplay="true"+:muted="true",让画面先出来 - 监听
@canplay或@loadedmetadata,就绪后立刻调videoContext.mute(false)尝试开声(部分机型仍需用户点一下屏幕) - 必须同时加
playsinline、webkit-playsinline、x5-playsinline,否则 iOS 微信里强制全屏 - H5 端首次加载后,必须等用户触发一次
touchstart,后续play()才真正可用
内存暴涨、滑动卡顿?90% 来自“全量渲染 video 标签”
一次性把 100 条视频都塞进 swiper-item,等于让浏览器同时解码 100 个视频首帧。iOS Safari 直接卡死,小程序白屏,App 内存飙升到 500MB+。
真实项目必须做可视区渲染:
- 只保留
current - 2到current + 2共 5 个swiper-item,其余用v-if="false"彻底移除 DOM - 每个
video加preload="none",首次进入可视区才调.load() - 滑出视口 500ms 后,执行
pause()并释放解码资源 - 慎用
autoplay: true,小程序建议设为false,等@loadedmetadata触发后再play()
全屏逻辑在不同平台差异极大,不能一套配置打天下
video 组件底层映射到各端原生能力,行为不一致是常态:
- 微信小程序:调用
requestFullScreen()后会进入系统全屏页,返回时触发@fullscreenchange,但无法自定义状态栏/导航栏样式 - App(iOS):
player-type="landscape"可强制横屏,但需在manifest.json中开启「横屏支持」,否则无效 - H5:无真正全屏,只能用
webkitRequestFullscreen()模拟,且部分安卓浏览器禁止自动全屏(需用户手势触发) - iOS 微信环境必须加
enable-play-gesture="true",否则点按无效
最易被忽略的是:真机调试时,iOS 微信和抖音小程序对 object-fit: cover 支持极差,必须用 width: 100%; height: 100%; object-fit: cover !important; 强制生效,否则视频拉伸或留黑边。











