vue3 vant4实现抖音短视频功能

news2024/11/15 22:52:56

文章目录

  • 1. 实现效果
  • 2. 精简版核心代码
  • 3. 完整功能点(本文章不写,只写核心代码)

1. 实现效果

请添加图片描述

2. 精简版核心代码

  1. 使用的 vue3 + vant4组件
  2. 使用van-swipe进行轮播图切换实现
<template>
	<div :style="{
		width: width + 'px',
		overflow: 'hidden',
	}" class="container">
		<van-swipe :loop="true" vertical :height="height" :width="width" :show-indicators="false" @change="onChange"
			:style="{ height: height + 'px' }">
			<van-swipe-item v-for="(item, index) in videoList" :key="index" class="swiper-slide-item">
				<div @click="onVideoClick(item, index)" z-index="1" class="swiperItemVideo">
					<video class="videoPlayer" :id="'videoPlayer_' + index" ref="player" :key="index" :poster="item.poster"
						:src="item.src" :width="width" autoplay :muted="muteding" loop x5-video-player-type="h5"
						webkit-playsinline="true" x-webkit-airplay="true" x5-video-orientation="portraint"
						playsInline="true" x5-video-player-fullscreen="portraint" x5-video-ignore-metadata='true'></video>
					<van-image v-if="!playing" class="play w-[40px] h-[40px]" :src="getAssetsFile('icon/play.png')" />
				</div>
				<ShortsBottom ref="bottomRef" :item="item" />
			</van-swipe-item>
		</van-swipe>
	</div>
</template>
<script setup lang="ts" name="Setting">
import {
	getAssetsFile
} from '@/utils/tool'
const player = ref(null);
const currentIndex = ref(0);
const playing = ref(true);
const muteding = ref(true)
const width = ref(window.innerWidth);
const height = ref(window.innerHeight);
let bottomRef = ref(null)
let bottomHeight = ref(0);
const currentVideoInfo = ref({
	videoId: "",
});

/**
 * 切换视频
 */
const onChange = (index) => {
	console.log(index, "index")
	currentVideoInfo.value = {
		videoId: ""
	};
	const preVideoId = "videoPlayer_" + currentIndex.value;
	const preVideo: any = document.getElementById(preVideoId);
	if (preVideo) preVideo.pause();
	const nextVideoId = "videoPlayer_" + index;
	const nextVideo: any = document.getElementById(nextVideoId);
	if (nextVideo) nextVideo.play();
	currentIndex.value = index;
	player.value = nextVideo;
	playing.value = true
	if (index == videoList.length - 1) {
		console.log("没有更多了")
	}
};
/**
 * 播放|暂停
 */
const onVideoClick = (item, index) => {
	const video: any = document.getElementById("videoPlayer_" + index);
	if (video && playing.value) {
		video.pause();
		playing.value = false;
	} else {
		video.play();
		playing.value = true;
	}
};

onMounted(() => {
	if (bottomRef.value) {
		console.log(bottomRef.value[0].bottomHeight, 1)
		bottomHeight.value = bottomRef.value[0].bottomHeight
	}
	const index = currentIndex.value;
	const videos: any = document.querySelectorAll("video");
	for (const video of videos) {
		let videoId = "videoPlayer_" + index;
		if (video && video.id && video.id != videoId) {
			video.pause();
		} else {
			player.value = video;
		}
	}
});

onBeforeUnmount(() => {
	const videos: any = document.querySelectorAll("video");
	for (const video of videos) {
		if (video && video.id) {
			video.pause();
		}
	}
});

/**
 * 短视频列表
 */
const videoList = [{
	videoId: Date.now() + 1,
	title: "抖音美女主播,JK超短裙学生妆美女跳舞展示,爱了爱了。",
	poster: "http://img01.sogoucdn.com/app/a/201023/27e5400e26fbef1ea32f9aff60c0b015",
	src: "https://txmov2.a.yximgs.com/upic/2020/11/08/19/BMjAyMDExMDgxOTQxNTlfNTIzNDczMzQ0XzM4OTQ1MDk5MTI4XzFfMw==_b_Bc770a92f0cf153407d60a2eddffeae2a.mp4",
	uploadTime: "2023-11-08 19:41",
	ipLocation: "上海",
	author: {
		authorId: 101,
		avatar: "https://i02piccdn.sogoucdn.com/4f85fc70df81d04a",
		nickName: "陌路",
		genderName: "男"
	}
},
{
	videoId: Date.now() + 2,
	title: "御姐美女抖音作品,来个自拍视频把,好美啊。",
	poster: "http://img02.sogoucdn.com/app/a/201023/0866f6a339e58d647eb476f72045e980",
	src: "https://txmov2.a.yximgs.com/upic/2020/10/02/09/BMjAyMDEwMDIwOTAwMDlfMTIyMjc0NTk0Ml8zNjk3Mjg0NjcxOF8xXzM=_b_B28a4518e86e2cf6155a6c1fc9cf79c6d.mp4",
	uploadTime: "2023-10-02 09:41",
	ipLocation: "贵州",
	author: {
		authorId: 102,
		avatar: "http://img02.sogoucdn.com/app/a/201023/0866f6a339e58d647eb476f72045e980",
		nickName: "御姐呀",
		genderName: "女"
	}
},
{
	videoId: Date.now() + 3,
	title: "抖音主播可爱妹子新学的舞蹈,超可爱的美女主播。",
	poster: "https://i02piccdn.sogoucdn.com/2acf176d90718d73",
	src: "https://txmov6.a.yximgs.com/upic/2020/08/23/00/BMjAyMDA4MjMwMDMyNDRfMTYzMzY5MDA0XzM0ODI4MDcyMzQ5XzFfMw==_b_B9a1c9d4e3a090bb2815994d7f33a906a.mp4",
	uploadTime: "2023-08-23 00:41",
	ipLocation: "广州",
	author: {
		authorId: 103,
		avatar: "https://i02piccdn.sogoucdn.com/2acf176d90718d73",
		nickName: "野花猫",
		genderName: "女"
	}
},
{
	videoId: Date.now() + 4,
	title: "多个美女带着遮阳帽出去散步自拍视频,好好看。",
	poster: "https://i02piccdn.sogoucdn.com/45c34c84c106bbb7",
	src: "https://alimov2.a.yximgs.com/upic/2020/07/02/14/BMjAyMDA3MDIxNDUyMDlfOTExMjIyMjRfMzE1OTEwNjAxNTRfMV8z_b_Bf3005d42ce9c01c0687147428c28d7e6.mp4",
	uploadTime: "2023-07-02 14:41",
	ipLocation: "山西",
	author: {
		authorId: 104,
		avatar: "https://i02piccdn.sogoucdn.com/45c34c84c106bbb7",
		nickName: "蓝姬",
		genderName: "女"
	}
},
];
</script>
<style lang="less" scoped>
.container {
	display: flex;
	flex-direction: column;
	overflow: hidden;

	.swiper-wrapper {
		flex: 1;
	}

	.swiper-slide-item {
		display: flex;
		flex-direction: column;
		width: 100%;

		.swiperItemVideo {
			z-index: 1;
			flex: 1;
			overflow-y: auto;
			width: 100%;
			position: relative;

			.play {
				position: absolute;
				z-index: 2;
				content: "";
				top: 50%;
				left: 50%;
				transform: translate(-50%, -50%);
				animation: move 0.3s linear alternate;
			}
		}

		.videoPlayer {
			background: #000;
			height: 100%;
			z-index: 2;
		}
	}
}

@keyframes move {
	0% {
		transform: translate(-50%, -50%) scale(2);
		opacity: 0;
	}

	100% {
		transform: translate(-50%, -50%) scale(1);
		opacity: 1;
	}
}
</style>
  1. ShortsBottom 组件代码
<template>
	<div class="videoInfo" ref="bottomRef">
		<div class="top mb-[8px]">
			<van-image class="logo w-[40px] h-[40px] mr-[8px]" round :src="getAssetsFile('logo.png')" />
			<span class="nickName  mr-[12px]">{{ item.author.nickName }}</span>
			<div class="btn-content" @click="Follow">
				<van-button type="primary" size="small" class="btn">Follow</van-button>
			</div>
			<div class="closeSound">
				<van-image class="logo w-[16px] h-[16px]" :src="getAssetsFile('icon/closeSound.png')" />
			</div>
		</div>
		<van-text-ellipsis class="title" :content="item.title" />
	</div>
</template>
<script setup lang="ts">
	import { ref, onMounted } from "vue";
	import { getAssetsFile } from '@/utils/tool'
	interface Props {
		item : any;
	}
	const props = withDefaults(defineProps<Props>(), {
		item: {},
	});
	let bottomRef = ref(null)
	let bottomHeight = ref(0)
	const Follow = ()=>{
		console.log("关注")
	}
	onMounted(() => {
		if (bottomRef.value) {
			bottomHeight.value = bottomRef.value.offsetHeight
		}
	});
	defineExpose({ bottomHeight })//暴露子组件的方法或者数据
</script>

<style lang="less" scoped>
	.videoInfo {
		background: #161616;
		color: #f5f5f5;
		padding: 16px 20px 34px 16px;
		text-align: left;
		position: relative;

		&::after {
			position: absolute;
			display: block;
			content: "";
			bottom: 0px;
			left: 0;
			width: 100%;
			height: 0px;
			background: red;
			z-index: 1;
		}

		.top {
			display: flex;
			justify-content: flex-start;
			align-items: center;

			.nickName {
				font-family: HarmonyOS Sans SC, HarmonyOS Sans SC;
				font-weight: 700;
				font-size: 14px;
				color: #FFFFFF;
				line-height: 14px;
			}

			.closeSound {
				margin-left: auto;
				width: 32px;
				height: 32px;
				padding: 8px;
				border-radius: 50%;
				background: rgba(255, 255, 255, 0.1);
			}
		}

		.title {
			font-family: HarmonyOS Sans SC, HarmonyOS Sans SC;
			font-weight: 400;
			font-size: 14px;
			color: #FFFFFF;
			line-height: 14px;
		}

	}
</style>

3. 完整功能点(本文章不写,只写核心代码)

  • 视频点赞
  • 视频分享
  • 视频用户基础信息
  • 视频暂停/播放
  • 视频声音控制
  • 上下切换视频
  • 视频封面图设置
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1713020.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spark中的累加器与广播变量及blockmanager图解

一、累加器 1、累加器的引入 案例&#xff1a;没读取一条文件中的数据&#xff0c;count1&#xff0c;并打印在Drive端&#xff08;控制台&#xff09; import org.apache.spark.{SparkConf, SparkContext} import org.apache.spark.rdd.RDDobject Demo20Accumulator {def ma…

做电商,错过了2020年的抖音!那2024一定要选择视频号小店!

哈喽~我是电商月月 电商老板们集合了&#xff0c;问大家一个问题: 如果能让你回到三四年前&#xff0c;抖音才步入大众视野&#xff0c;这时候让你去做抖音小店&#xff0c;你愿意吗&#xff1f; 我敢相信&#xff01;很多&#xff0c;错过当年抖音红利的商家&#xff0c;一…

【每日力扣】300. 最长递增子序列 与 139. 单词拆分

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害 300. 最长递增子序列 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而来的序列&…

【计算机网络】P1 计算机网络概念、组成、功能、分类、标准化工作以及性能评估指标

目录 1 什么是计算机网络2 计算机网络的组成2.1 组成部分上2.2 工作方式上2.3 功能组成上 3 计算机网络的功能3.1 数据通信3.2 资源共享3.3 分布式处理3.4 提高可靠性3.5 负载均衡 4 计算机网络的分类4.1 按分布范围分类4.2 按传输技术分类4.3 按照拓扑结构分类4.4 按使用者分类…

网络智能化的发展对仿真环境的需求

1. 网络智能化背景介绍 1.1 什么是网络智能化 网络智能化是指利用人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;、优化算法等技术来实现网络的信息化、自动化和智能化。相对5G、6G、算力网络等领域&#xff0c;网络智能化是针对网络全场景、全要素…

低调收藏,这份MobaXterm使用指南很全面

中午好&#xff0c;我的网工朋友。 MobaXterm&#xff0c;这个名字对于我们这些经常需要在Windows环境下与Linux服务器打交道的人来说&#xff0c;应该并不陌生。它不仅仅是一个SSH客户端&#xff0c;更是一个功能强大的终端工具箱&#xff0c;集成了X服务器和Unix命令集&…

HiWoo Box工业4G网关

在飞速发展的工业4.0时代&#xff0c;数据已成为驱动工厂智能化、自动化的核心力量。而如何将这些散布在工厂各个角落的数据高效、安全地汇集起来&#xff0c;成为企业提升生产效率、降低运营成本的关键。今天&#xff0c;我们将为您介绍一款4G网关产品——HiWoo Box&#xff0…

【嵌入式模块芯片开发】DWIN的T5L _DGUS应用开发 显示屏的基本图形显示以及串口命令的动态数据波形功能实现

【嵌入式模块芯片开发】DWIN的T5L _DGUS应用开发 显示屏的基本图形显示以及串口命令的动态数据波形功能实现 T5L _DGUS应用在DWIN的各类显示屏中 如DMG80480T070_05WTR等等 可用DWIN官方工具生成一系列上位机显示控件 通过串口命令进行交互实现显示、触摸等功能 也可以进行C51…

【上】王树森《小红书推荐系统公开课》- 课程笔记(推荐系统基础、召回、排序)

写在前面 本文为王树森老师《小红书推荐系统公开课》的课程笔记 课程来源&#xff1a;ShusenWang的个人空间-ShusenWang个人主页-哔哩哔哩视频 (bilibili.com)课程资料&#xff1a;GitHub - wangshusen/RecommenderSystem 由于篇幅较长&#xff0c;分为【上】【下】两篇文章…

HTML静态网页成品作业(HTML+CSS)——动漫海贼王介绍网页(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

VSCode 报错 之 运行 js 文件报错 ReferenceError: document is not defined

1. 背景 持续学习ing 2. 遇到的问题 在VSCode 右键 code runner js 文件报错 ReferenceError: document is not defined eg&#xff1a; // 为每个按钮添加点击事件监听器 document.querySelectorAll(button).forEach(function (button) {button.addEventListener(click, f…

全面盘点多模态融合算法及应用场景

关注作者&#xff0c;分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验&#xff0c;同济本复旦硕博&#xff0c;复旦机器人智能实验室成员&#xff0c;阿里云认证的资深架构师&#xff0c;项目管理专业人士&#xff0c;上亿营收AI产品研发负责人 多…

AI 绘图要如何入门?有哪些好用的软件推荐?(附工具+教程+变现模式)

1.Ai绘画如何入门 不需要把Ai绘画想的很复杂 抛去复杂的应用 使用现成简单的工具 只需要学会提示词 描述你想要的画面即可 提示词 不需要太复杂&#xff0c;也不能太简单&#xff0c;太简单依赖于ai的基本样式&#xff0c;关键是要抓住你想要的核心描述 AI不太擅长理解人类的…

Flask和Django的对比

文章目录 1. 简介FlaskDjango 2. 安装和创建项目FlaskDjango 3. URL路由FlaskDjango 4. 数据库支持FlaskDjango 5. 管理后台FlaskDjango 6. 总结 Flask和Django都是Python Web框架&#xff0c;它们在开发Web应用程序时都能提供强大的功能。本文将对这两个框架进行对比&#xff…

PPT 隐藏开启对象图层

目录预览 一、问题描述二、解决方案三、参考链接 一、问题描述 制作PPT的时候&#xff0c;有时候需要在一张PPT放置多个依次出现的内容&#xff0c;然后设置对应的动画&#xff0c;要是需要对某个内容进行修改的话&#xff0c;就会很不方便&#xff0c;这个时候就需要使用&…

微信小程序上架,AI类目审核(AI问答、AI绘画、AI换脸)

小程序对于生成式AI类目的产品上架审核较为严格&#xff0c;这也是近两年新增了几个类目&#xff0c;一旦小程序中涉及生成式AI相关的内容&#xff0c;如果你选择相应类目&#xff0c;但审核被划归为这一类&#xff0c;都需要准备此类目的审核&#xff0c;才能正常上架。 如果…

淘宝API探秘:一键获取店铺所有商品的魔法之旅

在数字时代的今天&#xff0c;数据已经成为了商业世界中的魔法石。而对于淘宝店主或者那些想要深入探索淘宝数据的人来说&#xff0c;淘宝API就像是打开阿里巴巴宝藏库的钥匙。今天&#xff0c;我们就来一起探索如何使用淘宝API&#xff0c;特别是如何获取店铺所有商品的接口&a…

倩女幽魂手游攻略:新人入坑必看指南!

《倩女幽魂》是一款经典的MMORPG游戏&#xff0c;凭借其丰富的剧情、精美的画面和多样的玩法&#xff0c;吸引了众多玩家。在游戏中&#xff0c;提升角色等级和战斗力是每个玩家的核心目标。本文将详细介绍如何在游戏中快速提升角色等级、增强实力&#xff0c;并提供一些实用的…

MT2076 小码哥处理订单

思路&#xff1a; 使用二分&#xff1a;题目中隐含条件&#xff1a;如果不满足&#xff0c;需要找到第一个不满足的订单。 二分法需要满足单调性or有一个界线使前后两部分性质相反。这里的”界线“为&#xff1a;是否满足条件。假设第i天无法满足&#xff0c;则后面的所有天都…

【跟着例子学MySQL】SQL进阶 – 视图、事务和变量

文章目录 前言回顾视图事务用户变量未完待续 前言 举例子&#xff0c;是最简单有效的学习方法。本系列文章以一个贯穿始终的场景&#xff0c;结合多个实例讲解MySQL的基本用法。 ❔ 为什么要写这个系列&#xff1f; 模仿是最好的老师&#xff0c;实践是检验成果的方法。本系列…