文章目录
- 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. 完整功能点(本文章不写,只写核心代码)
- 视频点赞
- 视频分享
- 视频用户基础信息
- 视频暂停/播放
- 视频声音控制
- 上下切换视频
- 视频封面图设置
