微信小程序之抖音微视无限滑动视频列表自定义组件编写

一.先上效果图

看到上面,你可能首先会想到,使用swiper然后将swiper的circular设置为true,那么,想象一下,假如视频很多的情况下,1千个,甚至上万个的情况下,只要有一个swiper-item,就会渲染一个Video播放器,这样是非常耗费性能的,本文将在这个基础上做优化,大致思路就是,不管我们的数据有多少条,我们都只渲染3个swiper-item,再配合swiper的切换,切换swiper-item的内容实现复用

二.swiper实现循环滑动

<view class="video-swiper-container"><swiper class="video-swiper" circular vertical><swiper-item wx:for="{{_videoList}}" wx:key="*this"><view class="video_item" style="background:{{index % 3 == 0 ? '#f00' : (index % 3 == 1 ? '#0f0':'#00f')}}">{{item.index}}  </view></swiper-item></swiper>
</view>
videoList: {type: Array,value: [],observer: function observer() {let newVal = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];let _videoList = newVal.map((item, index) => {let result = {index: index,url: item,objectFit: 'contain'}return result;})this.setData({_videoList: _videoList})}
}

代码很简单,只是将swiper的circular设置为了true,并且指定滑动方向为垂直方向,至于video标签,咱们先用一个View标签替换

三.第一次初始化

如果数据本身就小于3条,那么直接把传入的数据全部渲染,swiper默认选中第一个即可,如果数据大于3条,需要根据传入的index确定第一次加载时,swiper-item需要渲染的三个数据项,swiper默认选中第二个

  • 如果传入的index是0,那么,swiper依次渲染最后一条,第一条,第二条

  • 如果传入的index是最后一个,那么依次渲染倒数第二条,最后一条,第一条

  • 如果传入的index是其他位置的,则依次渲染上一条,当前index,下一条

<view class="video-swiper-container"><swiper class="video-swiper" circular vertical current="{{_videoList.length >= 3 ? 1:playIndex}}"><swiper-item wx:for="{{curQueue}}" wx:key="*this"><view class="video_item" style="background:{{index % 3 == 0 ? '#f00' : (index % 3 == 1 ? '#0f0':'#00f')}}">{{item.index}}  </view></swiper-item></swiper>
</view>
videoList: {type: Array,value: [],observer: function observer() {let newVal = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];let _videoList = newVal.map((item, index) => {let result = {index: index,url: item,objectFit: 'contain'}return result;})this.setData({_videoList: _videoList})this._videoListChange()}
},
playIndex: {type: Number,value: 0
}
_videoListChange: function() {let playIndex = this.data.playIndex;let curQueue = this.data.curQueue;let videoList = this.data._videoList;if(curQueue.length <= 0) {if (videoList.length >= 3) {if (playIndex == 0) {curQueue[0] = videoList[videoList.length - 1]curQueue[1] = videoList[0]curQueue[2] = videoList[1]} else if (playIndex == videoList.length - 1) {curQueue[0] = videoList[videoList.length - 2]curQueue[1] = videoList[videoList.length - 1]curQueue[2] = videoList[0]} else {curQueue[0] = videoList[playIndex - 1]curQueue[1] = videoList[playIndex]curQueue[2] = videoList[playIndex + 1]}} else {curQueue = videoList;}this.setData({curQueue: curQueue})}
}

四.配合swiper的切换,切换swiper-item的内容实现复用

当swiper切换完成后,判断是向上滑动切换到下一个,还是向下滑动切换上一个,假如总共有5条数据

  • 向上滑动切换下一个

一开始,第二个swiper-item被选中,实际显示的是第一条数据

第一次向上滑动切换后,此时会切换到第三个swiper-item,实际显示的是第二条数据,只需要将第一个swiper-item显示的内容设置成第三条数据;

再一次向上滑动切换后,此时会切换到第一个swiper-item,实际显示的是第三条数据,只需要将第二个swiper-item显示的内容设置成第四条数据;

再一次向上滑动切换后,此时会切换到第二个swiper-item,实际显示的是第四条数据,只需要将第三个swiper-item显示的内容设置成第五条数据;

再一次向上滑动切换后,此时会切换到第三个swiper-item,实际显示的是第五条数据,只需要将第一个swiper-item显示的内容设置成第一条数据;

  • 向下滑动切换上一个

一开始,第二个swiper-item被选中,实际显示的是第一条数据

第一次向下滑动切换后,此时会切换到第一个swiper-item,实际显示的是第五条数据,只需要将第三个swiper-item显示的内容设置成第四条数据;

再一次向下滑动切换后,此时会切换到第三个swiper-item,实际显示的是第四条数据,只需要将第二个swiper-item显示的内容设置成第三条数据;

再一次向下滑动切换后,此时会切换到第二个swiper-item,实际显示的是第三条数据,只需要将第一个swiper-item显示的内容设置成第二条数据;

再一次向下滑动切换后,此时会切换到第一个swiper-item,实际显示的是第二条数据,只需要将第三个swiper-item显示的内容设置成第一条数据;

<view class="video-swiper-container"><swiper class="video-swiper" circular vertical current="{{_videoList.length >= 3 ? 1:playIndex}}" bindchange="onSwiperChange"><swiper-item wx:for="{{curQueue}}" wx:key="*this"><view class="video_item" style="background:{{index % 3 == 0 ? '#f00' : (index % 3 == 1 ? '#0f0':'#00f')}}">{{item.index}}  </view></swiper-item></swiper>
</view>
data: {curQueue:[],_last: -1,
},onSwiperChange: function (event) {let _data = this.data;let _last = _data._last;let curQueue = _data.curQueue;let current = event.detail.current;let videoList = _data._videoList;if (videoList.length >= 3) {let diff = current - _last;if (diff === 0) return;this.data._last = current;let direction = diff === 1 || diff === -2 ? 'up' : 'down';/let curItem = curQueue[current]let realIndex = curItem.indexif (direction == 'up') {let change = (current + 1) % 3let next = (realIndex + 1) % videoList.lengthcurQueue[change] = videoList[next]} else {let change = (current - 1) < 0 ? 2 : current - 1let pre = (realIndex - 1) < 0 ? (videoList.length - 1) : (realIndex - 1)curQueue[change] = videoList[pre]}this.setData({curQueue: curQueue}) }
}

五.最后把View换成Video,并控制播放即可

<view class="video-swiper-container"><swiper class="video-swiper" circular vertical current="{{_videoList.length >= 3 ? 1:playIndex}}" bindchange="onSwiperChange"><swiper-item wx:for="{{curQueue}}" wx:key="*this"><view class="video_item" style="background:{{index % 3 == 0 ? '#f00' : (index % 3 == 1 ? '#0f0':'#00f')}}"><video style="width: 100%; height: 100%;" id="video_{{index}}" loop="{{loop}}" enable-play-gestureenable-progress-gesture show-center-play-btn="{{false}}" direction="0" controls="{{true}}" src="{{item.url}}"object-fit="{{item.objectFit || 'cover'}}"/></view></swiper-item></swiper>
</view>
Component({/*** 组件的属性列表*/properties: {videoList: {type: Array,value: [],observer: function observer() {let newVal = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];let _videoList = newVal.map((item, index) => {let result = {index: index,url: item,objectFit: 'contain'}return result;})this.setData({_videoList: _videoList})this._videoListChange()}},playIndex: {type: Number,value: 0},},lifetimes: {attached: function attached() {this.data._videoContexts = [wx.createVideoContext('video_0', this), wx.createVideoContext('video_1', this), wx.createVideoContext('video_2', this)];}},/*** 组件的初始数据*/data: {curQueue:[],_last: 1,_videoContexts: []},/*** 组件的方法列表*/methods: {_videoListChange: function() {let playIndex = this.data.playIndex;let curQueue = this.data.curQueue;let videoList = this.data._videoList;if(curQueue.length <= 0) {if (videoList.length >= 3) {if (playIndex == 0) {curQueue[0] = videoList[videoList.length - 1]curQueue[1] = videoList[0]curQueue[2] = videoList[1]} else if (playIndex == videoList.length - 1) {curQueue[0] = videoList[videoList.length - 2]curQueue[1] = videoList[videoList.length - 1]curQueue[2] = videoList[0]} else {curQueue[0] = videoList[playIndex - 1]curQueue[1] = videoList[playIndex]curQueue[2] = videoList[playIndex + 1]}} else {curQueue = videoList;}this.setData({curQueue: curQueue}, () => {this.playCurrent(videoList.length >= 3 ? 1:playIndex);}) }},onSwiperChange: function (event) {let _data = this.data;let _last = _data._last;let curQueue = _data.curQueue;let current = event.detail.current;let videoList = _data._videoList;if (videoList.length >= 3) {let diff = current - _last;if (diff === 0) return;this.data._last = current;let direction = diff === 1 || diff === -2 ? 'up' : 'down';/let curItem = curQueue[current]let realIndex = curItem.indexif (direction == 'up') {let change = (current + 1) % 3let next = (realIndex + 1) % videoList.lengthcurQueue[change] = videoList[next]} else {let change = (current - 1) < 0 ? 2 : current - 1let pre = (realIndex - 1) < 0 ? (videoList.length - 1) : (realIndex - 1)curQueue[change] = videoList[pre]}this.setData({curQueue: curQueue}, () => {this.playCurrent(current);}) }},playCurrent: function playCurrent(current) {let curQueue = this.data.curQueuethis.data._videoContexts.forEach((ctx, index) => {if(index !== current) {ctx.pause()ctx.seek(0)} else {ctx.play()}});},}
})

17_微信小程序之抖音微视无限滑动视频列表自定义组件编写相关推荐

  1. 微信小程序像抖音一样上滑视频

    莫名其妙的孤独和无可救药的喜欢. 首先你想要的东西是这样的嘛? 视频是上滑 加载下一个视频的 默认数据 export const list1 = [{id: 1,title: '标题1',like: ...

  2. 从微信小程序到抖音小程序:转换指南

    抖音小程序是一种新兴的小程序平台,与微信小程序类似,都是基于小程序框架的开发,不过两者的开发环境和API有所不同.如果你已经开发了一款微信小程序,想要将其转换为抖音小程序,可以按照以下步骤进行: 1. ...

  3. 微信小程序和抖音小程序的区别?如何选择?

    随着5G的到来,电商向多元化新型电商的转型也已成时代必然.2020年,当我们的Vlog.自媒体行业风生水起时,依托第三方的电商平台销售模式已经逐渐难以满足新型电商的应用场景,例如微信的私域流量.抖音对 ...

  4. 微信小程序与抖音小程序的区别

    1. 前缀区别:tt 与 wx 2. 调用前一个页面的方法时 微信小程序 let pages = getCurrentPages(); let prePage = pages[pages.length ...

  5. 微信小程序实现抖音切换视频效果

    微信小程序实现抖音切换视频效果 思路: 使用微信小程序的swiper组件,使其竖向滑动 分页加载,每次加载3个视频,当滑动到只剩1个视频时加载下一页 问题: 加载多个视频时,多个视频会同时播放 效果图 ...

  6. 微信小程序仿抖音上下滑动整屏切换视频

    微信小程序仿抖音上下滑动整屏切换视频 使用官网上面的扩展组件 官方使用的方式: 可结合自己业务修改: 使用官网上面的扩展组件 https://developers.weixin.qq.com/mini ...

  7. 微信小程序仿抖音视频

    微信小程序仿抖音视频 使用轮播图实现视频滑动效果. wxml 部分 <view class="video-contain"><!-- 自定义头部 -->&l ...

  8. 微信小程序仿抖音项目实战说明

    功能说明 短视频管理后台: 1.bgm管理(增删改查.文件上传.点击播放) 2.用户列表 3.举报管理 4.用户视频管理 因为微信端Api接口管理后台是围绕微信端功能做的,所以这里我就将功能列举到一起 ...

  9. 微信小程序——仿抖音短视频切换效果

    一直以为抖音短视频切换假如用小程序做的话应该是比较简单的,直接用swiper实现就好,但在实际写的过程中才发现没那么简单,要控制的逻辑还是挺多的. 还是先看效果 体验路径 自定义组件系列>> ...

最新文章

  1. matlab nt什么意思,胎儿nt是什么意思
  2. java svn插件_Eclipse安装SVN插件
  3. 我在Archlinux下使用的软件
  4. (39)通过 PID 获取 EPROCESS
  5. 《系统集成项目管理工程师》必背100个知识点-60干系人管理
  6. 解决 Tomcat 下 getInitParameter 返回 null
  7. 【云栖大会】探索云时代下的游戏开发模式
  8. python 战舰_简单Python战舰
  9. 为什么会有ResNet? Why ResNet?
  10. dbvisulizer 存储过程
  11. 烂泥:apache虚拟主机的学习与应用
  12. 自动驾驶 2-3 软件架构 Software Architecture
  13. 一直弹出adb已停止工作(远程主机强迫关闭现有的连接)的最简单完美解决法
  14. 集成电路经典资料分享
  15. DiskPart-删除磁盘分区
  16. HNSWNSG-基于图的ANN近邻搜索
  17. length () 和 length 的区别
  18. @Scheduled使用及讲解
  19. 修改网页视频播放速度
  20. 移动端测试——移动端基础

热门文章

  1. CAD设置靶心的大小
  2. 预先下载的keras库中神经网络模型指定存放路径及如何上传的问题
  3. 【新周报(049)】Datawhale组队学习
  4. Android手机平板根目录详解
  5. java自行车内走线,科普向 公路车有几种全内走线方式?
  6. Power BI应用案例:销售帕累托分析(28法则)
  7. 网络——介质访问控制
  8. Log4j日志框架介绍
  9. 简单记录使用org.slf4j.MDC进行日志追踪
  10. 微信发朋友圈如何只发文字?