vue3 vant4实现抖音短视频功能
文章目录
- 1. 实现效果
- 2. 精简版核心代码
- 3. 完整功能点(本文章不写,只写核心代码)
1. 实现效果

2. 精简版核心代码
- 使用的
vue3+vant4组件 - 使用
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 = trueif (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>
- 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. 完整功能点(本文章不写,只写核心代码)
- 视频点赞
- 视频分享
- 视频用户基础信息
- 视频暂停/播放
- 视频声音控制
- 上下切换视频
- 视频封面图设置

相关文章:
vue3 vant4实现抖音短视频功能
文章目录 1. 实现效果2. 精简版核心代码3. 完整功能点(本文章不写,只写核心代码) 1. 实现效果 2. 精简版核心代码 使用的 vue3 vant4组件使用van-swipe进行轮播图切换实现 <template><div :style"{width: width px,overflo…...
C#结合JS实现HtmlTable动态添加行并保存到数据库
目录 需求 效果视频演示 范例运行环境 准备数据源 数据表设计 UI及表结构Json配置 Json数据包提交配置 设计实现 前端UI Javascript 脚本 Jquery引用 C# 服务端操作 小结 需求 在 Web 应用项目中,实现一对多录入的数据管理功能是一项常见的应用。因此…...
Unity Render Streaming 云渲染 外网访问
初版: 日期:2024.5.20 前言:临时思路整理,后期会详细补充 环境: 1. 阿里云服务器 需要安装好nodejs 、npm 2. windows电脑,需安装好 nodejs 、npm 3.Unity 2021.3.15f1 4.Unity Render Streaming …...
美易官方:Copilot全面升级!
Copilot的全面升级,无疑在科技界掀起了一场革命性的浪潮!微软在一夜之间推出的这50余项AI更新,不仅彰显了其在人工智能领域的深厚底蕴,更是让全球用户见证了计算机理解人类能力的一次飞跃。 在微软2024年Build开发者大会的主题演…...
深入了解FreeRTOS:实时操作系统的核心概念和应用
前言: 在当今数字化世界中,嵌入式系统扮演着至关重要的角色,从工业自动化到智能设备,无所不在。而实时操作系统(RTOS)则是这些系统的核心引擎,它们负责管理任务、资源和时间,确保系统…...
Spring框架学习笔记(五):JdbcTemplate 和 声明式事务
基本介绍:通过 Spring 框架可以配置数据源,从而完成对数据表的操作。JdbcTemplate 是 Spring 提供的访问数据库的技术。将 JDBC 的常用操作封装为模板方法 1 JdbcTemplate 使用前需进行如下配置 1.1 在maven项目的pom文件加入以下依赖 <dependencies…...
考研计组chap1计算机系统概述
目录 一、计算机发展历程(不考了) 二、计算机硬件的基本组成 3 1.五个部分 (1)输入设备 (2)控制器 (3)运算器 (4)(主)存储器 (5࿰…...
如何使用Python中的生成器
如何使用Python中的生成器 在Python中,生成器是一种特殊的迭代器,它允许你逐个地生成值,而不是一次性地计算并存储所有的值。这对于处理大量数据或者无限序列特别有用,因为它能够节省内存并提高效率。 生成器通常是通过以下两种…...
C语言 读取 MIDI文件头部
在C语言中直接读取MIDI文件并不简单,因为MIDI文件是一种包含音乐事件(如音符的开始和结束、控制信号等)的二进制格式,而不是像文本文件那样容易解析。不过,你可以通过以下步骤来实现: 了解MIDI文件格式&am…...
C# Winform实现五子棋游戏(代完善)
实现了基本的玩法。 BoardController.cs using System;namespace GomokuGame {public class BoardController{private static BoardController instance;private readonly int[,] board;private const int boardSize 15;private BoardController(){board new int[boardSize…...
文档档案管理系统整体建设方案书(实际项目原件word2024)
1.系统概述 1.1.需求描述 1.2.需求分析 1.3.重难点分析 1.4.重难点解决措施 2.系统架构设计 2.1.系统架构图 2.2.关键技术 数据备份技术 3.系统功能设计 3.1.功能清单列表 3.2.基础数据管理 3.3.位置管理 3.4.文档使用 3.5.文档管理 软件全套资料包获取方式①:软件项…...
React与Vue的区别?
一、区别: 1. 语法 Vue采用自己特有的模板语法; React是单向的,采用jsx语法创建react元素。 2.监听数据变化的实现原理不同 Vue2.0 通过Object.defineproperty()方法的getter/setter属性, 实现数据劫持, 每次修改完数据会触发diff算法(双端对比) …...
leetcode 2115.从给定原材料中找到所有可以做出的菜
思路:拓补排序,哈希表 在思路上其实很好发现,我们需要有一个明确的做菜顺序,也就是说需要定下来我们根据原材料先做哪些菜,然后做完该做的菜之后,后来又能做哪些菜。 你也发现了,这个顺序其实…...
Opencompass模型评测教程
模型评测 模型评测非常关键,目前主流的方法主要可以概括为主观评测和客观评测,主观评测又可以分为两种形式:人工判断或者和模型竞技场。客观评测一般采用评测数据集的形式进行模型评测。本教程使用Opencompass工具进行对Internlm2-7b模型进行…...
什么是安全测试,如何进行安全测试?
什么是安全测试? 概述 安全测试是一种旨在识别系统、网络或应用程序中的安全漏洞的测试方法。其目标是确保系统能够抵御恶意攻击,保护数据的机密性、完整性和可用性。安全测试通常包括漏洞扫描、渗透测试、代码审计和安全评估等多个方面。 安全测试的…...
ros的pcl库中对于自己定义的消息,调用pcl库时总是报错 c++
首先定义自己的消息类型 struct CustomPoint { // 定义点类型结构PCL_ADD_POINT4D; // 该点类型有4个元素float intensity 0.0;uint32_t zone;uint32_t ring;uint32_t sector;EIGEN_MAKE_ALIGNED_OPERATOR_NEW // 确保new操作符对齐操作 } EIGEN_ALIGN16; // 强制SSE对齐POIN…...
DataFrame—数据汇总6
文章最前: 我是Octopus,这个名字来源于我的中文名--章鱼;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github ;这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的…...
Java入门基础学习笔记41——实体类
实体JavaBean/实体类: 就是一种特殊形式的类。 1)这个类中的成员变量都要私有,并且要对外提供相应的getXXX,setXXX的方法。 2)类中必须要有一个公共的无参的构造器。其他的构造器可写可不写。 右键菜单中࿰…...
【Linux】信号之信号的保存和处理详解
🤖个人主页:晚风相伴-CSDN博客 💖如果觉得内容对你有帮助的话,还请给博主一键三连(点赞💜、收藏🧡、关注💚)吧 🙏如果内容有误或者有写的不好的地方的话&…...
基于Django的图书管理系统
文章目录 前言一、页面展示1.登录2.前端页面3.后端页面 二、项目上传(1)导入数据库(2)导入项目(3)数据库密码修改(4)进入网站 总结 前言 本网站调用Django编写了图书管理网站&#…...
地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...
Zustand 状态管理库:极简而强大的解决方案
Zustand 是一个轻量级、快速和可扩展的状态管理库,特别适合 React 应用。它以简洁的 API 和高效的性能解决了 Redux 等状态管理方案中的繁琐问题。 核心优势对比 基本使用指南 1. 创建 Store // store.js import create from zustandconst useStore create((set)…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...
Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别
OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
