# ShortVideo 短视频 3.5.7

短视频组件通常用于App中实现上下滑动切换短视频的功能,类似抖音等短视频应用的效果。

# 平台差异说明

App(vue) App(nvue) H5 小程序

# 基本使用

  • 通过tabsList(设置顶部分类标签),videoList(设置视频数据列表),currentTab(当前选中的tab索引),currentVideo(当前播放的视频索引)
  • 通过各种事件监听实现交互功能,如@tabChange(标签切换)、@videoChange(视频切换)、@like(点赞)等
<template>
	<view class="page">
		<u-short-video 
			:tabs-list="tabsList"
			:video-list="videoList"
			:current-tab="currentTab"
			:current-video="currentVideo"
			@tabChange="onTabChange"
			@videoChange="onVideoChange"
			@like="onLike"
			@comment="onComment"
			@share="onShare"
			@collect="onCollect"
		>
		</u-short-video>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				currentTab: 0,
				currentVideo: 0,
				tabsList: [
					{ name: '推荐' },
					{ name: '关注' },
					{ name: '朋友' },
					{ name: '本地' }
				],
				videoList: [
					{
						videoUrl: 'http://qn-o.jiangruyi.com/rjtsdl.MP4',
						progress: 0,
						bgColor: '#000',
						author: {
							avatar: '/static/avatar1.jpg',
							name: '创作者1',
							desc: '这是一段视频描述'
						},
						isLiked: false,
						likeCount: 128,
						commentCount: 25,
						shareCount: 12,
						collectCount: 8,
						isCollected: false
					},
					{
						videoUrl: 'http://qn-o.jiangruyi.com/shanghai.mp4',
						progress: 0,
						bgColor: '#000',
						author: {
							avatar: '/static/avatar2.jpg',
							name: '创作者2',
							desc: '记录美好生活'
						},
						isLiked: true,
						likeCount: 863,
						commentCount: 96,
						shareCount: 32,
						collectCount: 45,
						isCollected: true
					}
				]
			}
		},
		methods: {
			onTabChange(index) {
				console.log('切换tab到:', index);
				this.currentTab = index;
			},
			onVideoChange(index) {
				console.log('切换视频到:', index);
				this.currentVideo = index;
			},
			onLike({ item, index }) {
				console.log('点赞视频:', index);
				// 更新点赞状态和数量
				this.videoList[index].isLiked = !this.videoList[index].isLiked;
				this.videoList[index].likeCount += this.videoList[index].isLiked ? 1 : -1;
			},
			onComment({ item, index }) {
				console.log('评论视频:', index);
				uni.showToast({
					title: '评论功能',
					icon: 'none'
				});
			},
			onShare({ item, index }) {
				console.log('分享视频:', index);
				uni.showToast({
					title: '分享功能',
					icon: 'none'
				});
			},
			onCollect({ item, index }) {
				console.log('收藏视频:', index);
				// 更新收藏状态和数量
				this.videoList[index].isCollected = !this.videoList[index].isCollected;
				this.videoList[index].collectCount += this.videoList[index].isCollected ? 1 : -1;
			}
		}
	}
</script>

# 自定义插槽示例

<template>
	<view class="page">
		<u-short-video 
			:tabs-list="tabsList"
			:video-list="videoList"
			:current-tab="currentTab"
			:current-video="currentVideo"
			@tabChange="onTabChange"
			@videoChange="onVideoChange"
			@like="onLike"
			@comment="onComment"
			@share="onShare"
			@collect="onCollect"
		>
			<!-- 自定义菜单按钮 -->
			<template #menu>
				<view class="custom-menu">
					<up-icon name="grid" size="22px" color="#ddd"></up-icon>
				</view>
			</template>
			
			<!-- 自定义搜索按钮 -->
			<template #search>
				<view class="custom-search">
					<up-icon name="search" size="22px" color="#ddd"></up-icon>
				</view>
			</template>
			
			<!-- 自定义操作按钮 -->
			<template #actions="{item, index}">
				<view class="custom-actions">
					<view class="action-item" @click="onLike({item, index})">
						<up-icon 
							:name="item.isLiked ? 'thumb-up-fill' : 'thumb-up'" 
							size="32px" 
							color="#eee"
						></up-icon>
						<text class="action-text">{{ item.likeCount }}</text>
					</view>
					<view class="action-item" @click="onComment({item, index})">
						<up-icon name="chat" size="32px" color="#eee"></up-icon>
						<text class="action-text">{{ item.commentCount }}</text>
					</view>
					<view class="action-item" @click="onShare({item, index})">
						<up-icon name="share" size="32px" color="#eee"></up-icon>
						<text class="action-text">{{ item.shareCount }}</text>
					</view>
					<view class="action-item" @click="onCollect({item, index})">
						<up-icon 
							:name="item.isCollected ? 'bookmark-fill' : 'bookmark'" 
							size="32px" 
							color="#eee"
						></up-icon>
						<text class="action-text">{{ item.collectCount }}</text>
					</view>
				</view>
			</template>
		</u-short-video>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				currentTab: 0,
				currentVideo: 0,
				tabsList: [
					{ name: '推荐' },
					{ name: '关注' },
					{ name: '朋友' },
					{ name: '本地' }
				],
				videoList: [
					{
						videoUrl: 'http://qn-o.jiangruyi.com/rjtsdl.MP4',
						progress: 0,
						bgColor: '#000',
						author: {
							avatar: '/static/avatar1.jpg',
							name: '创作者1',
							desc: '这是一段视频描述'
						},
						isLiked: false,
						likeCount: 128,
						commentCount: 25,
						shareCount: 12,
						collectCount: 8,
						isCollected: false
					},
					{
						videoUrl: 'http://qn-o.jiangruyi.com/shanghai.mp4',
						progress: 0,
						bgColor: '#000',
						author: {
							avatar: '/static/avatar2.jpg',
							name: '创作者2',
							desc: '记录美好生活'
						},
						isLiked: true,
						likeCount: 863,
						commentCount: 96,
						shareCount: 32,
						collectCount: 45,
						isCollected: true
					}
				]
			}
		},
		methods: {
			onTabChange(index) {
				console.log('切换tab到:', index);
				this.currentTab = index;
			},
			onVideoChange(index) {
				console.log('切换视频到:', index);
				this.currentVideo = index;
			},
			onLike({ item, index }) {
				console.log('点赞视频:', index);
				// 更新点赞状态和数量
				this.videoList[index].isLiked = !this.videoList[index].isLiked;
				this.videoList[index].likeCount += this.videoList[index].isLiked ? 1 : -1;
			},
			onComment({ item, index }) {
				console.log('评论视频:', index);
				uni.showToast({
					title: '评论功能',
					icon: 'none'
				});
			},
			onShare({ item, index }) {
				console.log('分享视频:', index);
				uni.showToast({
					title: '分享功能',
					icon: 'none'
				});
			},
			onCollect({ item, index }) {
				console.log('收藏视频:', index);
				// 更新收藏状态和数量
				this.videoList[index].isCollected = !this.videoList[index].isCollected;
				this.videoList[index].collectCount += this.videoList[index].isCollected ? 1 : -1;
			}
		}
	}
</script>

# 演示页面源代码地址

点击以下链接以查看演示页面的源码


 github  gitee

# API

# Props

参数 说明 类型 默认值 可选值
tabsList tabs标签列表 Array [ { name: '推荐' }, { name: '关注' }, { name: '朋友' }, { name: '本地' } ] -
videoList 视频列表数据 Array [] -
currentTab 当前选中的tab索引 Number 0 -
currentVideo 当前播放的视频索引 Number 0 -

# Events

事件名 说明 回调参数
tabChange tab切换时触发 index: 当前tab索引
videoChange 视频切换时触发 index: 当前视频索引
like 点赞时触发 { item, index }
comment 评论时触发 { item, index }
share 分享时触发 { item, index }
collect 收藏时触发 { item, index }
progressChanging 进度条拖动中触发 { progress, index }
progressChange 进度条值改变时触发 { progress, index }
videoPlay 视频播放时触发 { index, event }
videoPause 视频暂停时触发 { index, event }
videoEnded 视频结束时触发 { index, event }
timeUpdate 视频时间更新时触发 { index, event }
loadedMetadata 视频元数据加载完成时触发 { index, event }

# Slot

名称 说明
menu 顶部菜单区域
search 顶部搜索区域
actions 右侧操作区域
tabbar 底部导航栏区域