更新记录
1.0.2(2024-12-10) 下载此版本
- 优化界面展示效果以及示例代码完整性
- 优化操作逻辑
1.0.1(2024-12-10) 下载此版本
更新示例代码
1.0.0(2024-12-10) 下载此版本
first commit
查看更多平台兼容性
Vue2 | Vue3 |
---|---|
× | √ |
App | 快应用 | 微信小程序 | 支付宝小程序 | 百度小程序 | 字节小程序 | QQ小程序 |
---|---|---|---|---|---|---|
HBuilderX 4.36 | × | √ | × | × | × | × |
钉钉小程序 | 快手小程序 | 飞书小程序 | 京东小程序 |
---|---|---|---|
× | × | × | × |
H5-Safari | Android Browser | 微信浏览器(Android) | QQ浏览器(Android) | Chrome | IE | Edge | Firefox | PC-Safari |
---|---|---|---|---|---|---|---|---|
× | × | × | × | × | × | × | × | × |
简介
video-swiper一个基于 swiper 嵌套 video 实现仿抖音短视频组件,目前仅支持 H5、微信小程序
使用说明
建议运行示例工程,熟悉一下代码,有问题可以在问我
<template>
<view class="content">
<!-- 可能需要处理状态栏 -->
<view class="refresh">下拉刷新 </view>
<video-swiper :videos="videos" @refresh="onRefresh" @change="onChange">
<!-- 自定义loading -->
<template v-slot:loading>
<view class="loading full flex center"> 自定义loading </view>
</template>
<!-- 默认插槽 -->
<template v-slot="{ data }">
<view class="right-area">
id: {{ data.id }}
我是右侧区域
</view>
<view class="bottom-area"> 我是底部区域 </view>
</template>
</video-swiper>
<!-- 自己加动画效果,比如全屏转圈 -->
<!-- loading的时间就是家口请求的时间,有问题就加延迟 -->
<view class="loadmore"> 加载更多 </view>
</view>
</template>
<script setup>
import {
ref
} from "vue";
import videoSwiper from "@/uni_modules/cc-swiper-video/index.vue";
import cover from '@/static/cover.jpeg'
// 视频列表,这里只存储当前页的视频即可,组件内部会的处理
// 自己的代码逻辑只需要处理pageIndex和pageSize即可
const videos = ref([]);
// 应该一次性获取多条视频链接
// 然后合适的时候往视频数组中push
let id = 0;
const getVideos = async () => {
return new Promise((r) => {
// setTimeout(() => {
// videos.value = [{
// id: '123',
// url: 'http://127.0.0.1:8080/%E6%93%8D%E4%BD%9C%E8%A7%86%E9%A2%91.mp4',
// cover
// }]
// r();
// }, 1000)
// return
// const ip = "http://127.0.0.1:3000";
// 真机调试可以填入局域网地址
const ip = 'http://192.168.1.6:3000'
uni.request({
url: `${ip}/getVideo`,
success(res) {
const list = res.data.data;
videos.value = list.map((url, index) => {
return {
url,
id: ++id,
cover, // 视频封面,应该是视频的第一帧,不传的话会默认显示loading
};
});
r();
},
});
});
};
const onChange = async ({
videoIndex, // 当前的index
videoCount, // 所有的视频长度
}) => {
return
// 剩余4个视频的时候后台加载更多
// 如果使用这个方法,需要在onRefresh中当isInitLoad为flase时return
// 需要自己添加一个flag,防止多次请求数据
if (videoCount - videoIndex < 4) {
await getVideos()
}
};
// 初始化视频或者加载数据
// 这里只需要请求数据就可以了,组件内部会处理的
const onRefresh = async ({
finish,
isInitLoad
}) => {
// 如果是无限滚动方式解除“if(!isInitLoad)return ”代码注释走onChange逻辑
// 否则不走onChange代码,走上拉加载
// if(!isInitLoad)return
if (isInitLoad) {
id = 0
}
// 可以使用isInitLoad判断是刷新还是加载更多
// 上划加载或者初次加载数据
await getVideos();
finish && finish();
};
</script>
<style lang="scss" scoped>
.content {
width: 100vw;
height: 100vh;
background: green;
}
.full {
width: 100%;
height: 100%;
}
.flex {
display: flex;
}
.justify-center {
justify-content: center;
}
.items-center {
align-items: center;
}
.center {
justify-content: center;
align-items: center;
}
.loading {
position: relative;
background: rgba(0, 0, 0, 1);
color: white;
}
.right-area {
writing-mode: vertical-lr;
position: absolute;
z-index: 999;
right: 0;
bottom: 200rpx;
padding: 20rpx;
background: red;
}
.bottom-area {
position: absolute;
z-index: 999;
width: 100%;
height: 100rpx;
right: left;
bottom: 0;
background: pink;
}
.refresh {
position: absolute;
top: 30rpx;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
.loadmore {
position: absolute;
bottom: 30rpx;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
}
::v-deep .uni-video-container {
// 重写h5下的背景。如果有封面图可以改成毛玻璃的形式
background: black;
}
</style>
注意事项
-
如果没有视频接口可以使用 node 运行 server/index.js
这也是我网上找的api,代码里注释了原文地址
-
视频列表中的每项必须包括 url、id 字段,其他的预留字段
- cover::封面
- paused:是否暂停
- loaded:视频是否加载完毕
-
微信小程序切换首尾视频时会闪一下
如果视频条数不是3的倍数,然后使用上拉加载,组件内会处理一下当前的swiper的current,否则circular会有问题 如果不能接受请使用无限加载,或者接口返回的条数是3的倍数