Skip to content

ShortVideo 短视频 4.4.0

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

平台差异说明

|App(vue)|App(uvue/uni-app-x)|App(nvue)|H5|小程序| |:-😐:-😐:-😐:-😐:-😐:-😐 |√|√|√|√|

基本使用

  • 通过tabsList(设置顶部分类标签),videoList(设置视频数据列表),currentTab(当前选中的tab索引),currentVideo(当前播放的视频索引)
  • 通过各种事件监听实现交互功能,如@tabChange(标签切换)、@videoChange(视频切换)、@like(点赞)等
vue
<template>
	<view class="page">
		<up-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"
		>
		</up-short-video>
	</view>
</template>
js
<script setup>
import { ref } from 'vue';

const currentTab = ref(0);
const currentVideo = ref(0);

const tabsList = ref([
  { name: '推荐' },
  { name: '关注' },
  { name: '朋友' },
  { name: '本地' }
]);

const videoList = ref([
  {
    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
  }
]);

const onTabChange = (index) => {
  console.log('切换tab到:', index);
  currentTab.value = index;
};

const onVideoChange = (index) => {
  console.log('切换视频到:', index);
  currentVideo.value = index;
};

const onLike = ({ item, index }) => {
  console.log('点赞视频:', index);
  // 更新点赞状态和数量
  videoList.value[index].isLiked = !videoList.value[index].isLiked;
  videoList.value[index].likeCount += videoList.value[index].isLiked ? 1 : -1;
};

const onComment = ({ item, index }) => {
  console.log('评论视频:', index);
  uni.showToast({
    title: '评论功能',
    icon: 'none'
  });
};

const onShare = ({ item, index }) => {
  console.log('分享视频:', index);
  uni.showToast({
    title: '分享功能',
    icon: 'none'
  });
};

const onCollect = ({ item, index }) => {
  console.log('收藏视频:', index);
  // 更新收藏状态和数量
  videoList.value[index].isCollected = !videoList.value[index].isCollected;
  videoList.value[index].collectCount += videoList.value[index].isCollected ? 1 : -1;
};
</script>

自定义插槽示例

vue
<template>
	<view class="page">
		<up-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>
		</up-short-video>
	</view>
</template>
js
<script setup>
import { ref } from 'vue';

const currentTab = ref(0);
const currentVideo = ref(0);

const tabsList = ref([
  { name: '推荐' },
  { name: '关注' },
  { name: '朋友' },
  { name: '本地' }
]);

const videoList = ref([
  {
    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
  }
]);

const onTabChange = (index) => {
  console.log('切换tab到:', index);
  currentTab.value = index;
};

const onVideoChange = (index) => {
  console.log('切换视频到:', index);
  currentVideo.value = index;
};

const onLike = ({ item, index }) => {
  console.log('点赞视频:', index);
  // 更新点赞状态和数量
  videoList.value[index].isLiked = !videoList.value[index].isLiked;
  videoList.value[index].likeCount += videoList.value[index].isLiked ? 1 : -1;
};

const onComment = ({ item, index }) => {
  console.log('评论视频:', index);
  uni.showToast({
    title: '评论功能',
    icon: 'none'
  });
};

const onShare = ({ item, index }) => {
  console.log('分享视频:', index);
  uni.showToast({
    title: '分享功能',
    icon: 'none'
  });
};

const onCollect = ({ item, index }) => {
  console.log('收藏视频:', index);
  // 更新收藏状态和数量
  videoList.value[index].isCollected = !videoList.value[index].isCollected;
  videoList.value[index].collectCount += videoList.value[index].isCollected ? 1 : -1;
};
</script>

演示页面源代码地址

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


 github  gitee

API

Props

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

Events

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

Slot

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