手把手教你用前端实现短视频App(滑动切换)

Jacquelyn38
• 阅读 1589

前言

平常在玩短视频App时,喜欢看的视频可以多看一会,不喜欢看的视频直接往上一划,这个功能一直深受用户喜爱。今天我们不妨实现一个这样功能的App。

功能

  1. 上下滑动切换视频

  2. 可查看对应视频下的评论

示例

下面我挑出了几张代表性的图片,供大家参考。

手把手教你用前端实现短视频App(滑动切换)

手把手教你用前端实现短视频App(滑动切换)

手把手教你用前端实现短视频App(滑动切换)

下载链接

以上是我自己做的一款App的示例图,如果感兴趣的小伙伴,大家可以下载到手机上体验。目前只是开发了安卓版本。

`链接: https://pan.baidu.com/s/1dbgx9eht54qh-Ig04w2JAg   
提取码: 96ta   
复制这段内容后打开百度网盘手机App,操作更方便哦  
`

核心代码

<template>  
  <div class="home">  
    <van-swipe  
      style="height: 100vh"  
      vertical  
      @change="onChange"  
      :show-indicators="false"  
    >  
      <van-swipe-item>  
        <div class="main" v-if="isshow">  
          <video-player  
            v-if="playerOptions.sources[0].src"  
            class="video-player vjs-custom-skin"  
            ref="videoPlayer"  
            :playsinline="true"  
            :options="playerOptions"  
          ></video-player>  
          <div class="footbox">  
            <div class="foot">  
              <p class="user">@ {{ artistName }}</p>  
              <p class="name">{{ name }}</p>  
            </div>  
            <div class="pl" @click="openPl">  
              <van-icon name="chat" size="30" />  
            </div>  
          </div>  
        </div>  
      </van-swipe-item>  
      <van-swipe-item>  
        <div class="main" v-if="!isshow">  
          <video-player  
            v-if="playerOptions.sources[0].src"  
            class="video-player vjs-custom-skin"  
            ref="videoPlayer"  
            :playsinline="true"  
            :options="playerOptions"  
          ></video-player>  
          <div class="footbox">  
            <div class="foot">  
              <p class="user">@ {{ artistName }}</p>  
              <p class="name">{{ name }}</p>  
            </div>  
            <div class="pl" @click="openPl">  
              <van-icon name="chat" size="30" />  
            </div>  
          </div>  
        </div>  
      </van-swipe-item>  
    </van-swipe>  
    <van-action-sheet v-model="show" class="sheet">  
      <van-list  
        v-model="loading"  
        @load="onLoad"  
        :offset="1"  
        :immediate-check="false"  
      >  
        <div v-for="(item, index) in plist" :key="index" class="ovf pll">  
          <div class="pl-l"><img :src="item.user.avatarUrl" alt="" /></div>  
          <div class="pl-r">  
            <div class="name1">{{ item.user.nickname }}</div>  
            <div class="con">{{ item.content }}</div>  
          </div>  
        </div>  
      </van-list>  
    </van-action-sheet>  
  </div>  
</template>  

<script>  
import { list, mv, pl } from "@request/api";  
import "../video/index";  
import { videoPlayer } from "vue-video-player";  
export default {  
  name: "home",  
  data() {  
    return {  
      list: "",  
      id: "",  
      show: false,  
      dataLength: 1,  
      inx: 0,  
      artistName: "",  
      name: "",  
      isshow: true,  
      plist: "",  
      loading: false,  
      page: 10,  
      playerOptions: {  
        autoplay: true, //如果true,浏览器准备好时开始回放。  
        muted: false, // 默认情况下将会消除任何音频。  
        loop: false, // 导致视频一结束就重新开始。  
        preload: "auto", // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)  
        language: "zh-CN",  
        poster:"",  
        aspectRatio: "16:9", // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3")  
        fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。  
        sources: [{ type: "video/mp4", src: "" }],  
        width: document.documentElement.clientWidth,  
        notSupportedMessage: "此视频暂无法播放,请稍后再试", //允许覆盖Video.js无法播放媒体源时显示的默认信息。  
        controlBar: {  
          timeDivider: true, // 分时  
          durationDisplay: true, // 持续时间显示  
          remainingTimeDisplay: false, // 剩余时间显示  
          fullscreenToggle: false, //全屏按钮  
        },  
      },  
    };  
  },  
  components: {  
    videoPlayer,  
  },  
  mounted() {  
    this.wait();  
  },  
  methods: {  
    // 首次获取url  
    async wait() {  
      let id = await this.get();  
      let res = await mv(id);  
      // this.playerOptions.poster = this.poster;  
      this.$set(this.playerOptions, "poster", this.poster);  
      this.$set(this.playerOptions.sources[0], "src", res.data.url);  
    },  
    // 加载评论  
    onLoad() {  
      setTimeout(() => {  
        this.page += 10;  
        this.getpl();  
        this.loading = false;  
      }, 500);  
    },  
    // 获取数据  
    get() {  
      return list(this.dataLength).then((res) => {  
        console.log(res.data);  
        this.urlData = res.data;  
        this.poster = this.urlData[this.inx].cover;  
        this.id = this.urlData[this.inx].id;  
        this.artistName = this.urlData[this.inx].artistName;  
        this.name = this.urlData[this.inx].name;  
        // return this.id;  
        return Promise.resolve(this.id);  
        // 等价于  
        // return new Promise((resolve) => {  
        //   resolve(this.id)  
        // })  
      });  
    },  
    // 封装静态数据  
    getStatic(v) {  
      this.id = v[this.inx].id;  
      this.artistName = v[this.inx].artistName;  
      this.name = v[this.inx].name;  
      this.poster = v[this.inx].cover;  
      return this.id;  
    },  
    // 获取评论  
    getpl() {  
      pl(this.id, this.page).then((res) => {  
        if (document.querySelector(".van-action-sheet__content")) {  
          document.querySelector(".van-action-sheet__content").scrollTop = 0;  
        }  
        this.plist = res.comments;  
      });  
    },  
    // 滑动触发  
    async onChange() {  
      console.log(this.inx);  
      this.isshow = !this.isshow;  
      this.page = 10;  
      this.getpl();  
      if (this.inx < this.urlData.length - 1) {  
        this.inx += 1;  
        let id = this.getStatic(this.urlData);  
        let res = await mv(id);  
        this.$set(this.playerOptions.sources[0], "src", res.data.url);  
        this.$set(this.playerOptions, "poster", this.poster);  
        // this.playerOptions.poster = this.poster;  
      } else {  
        this.inx = 0;  
        this.dataLength += 1;  
        this.wait();  
      }  
    },  
    // 打开评论列表  
    openPl() {  
      this.show = true;  
      this.getpl();  
    },  
  },  
};  
</script>  
<style lang="less" scoped>  
.main {  
  height: 100%;  
}  
.footbox {  
  position: relative;  
  bottom: 0;  
  width: 95%;  
  margin: 0 auto;  
  display: flex;  
  justify-content: space-between;  
  align-items: center;  
}  
.user {  
  font-size: 14px;  
}  
.user,  
.name {  
  text-overflow: ellipsis;  
  overflow: hidden;  
  white-space: nowrap;  
}  
.foot {  
  width: 80%;  
  color: #fff;  
  font-size: 16px;  
  z-index: 10001;  
}  
.pl {  
  width: 10%;  
  color: #fff;  
  font-size: 16px;  
  z-index: 10001;  
}  
.sheet {  
  height: 50vh;  
  .pll {  
    overflow: hidden;  
    padding: 10px;  
    border-bottom: 1px solid #f4f4f4;  
    .pl-l {  
      width: 20%;  
      float: left;  
    }  
    .pl-l img {  
      width: 55%;  
      border-radius: 50%;  
      animation: all ds 0.5s;  
    }  
    @keyframes ds {  
      from {  
        opacity: 0;  
      }  
      to {  
        opacity: 1;  
      }  
    }  
    .pl-r {  
      width: 78%;  
      float: left;  
    }  
    .name1 {  
      font-size: 14px;  
      color: #666;  
      font-weight: bold;  
      margin-bottom: 5px;  
    }  
    .con {  
      width: 100%;  
      line-height: 24px;  
      color: #333333;  
      font-size: 14px;  
    }  
  }  
}  
</style>  

完整代码库

恭请各位大佬指正。

https://github.com/maomincoding/zm_mv2  

欢迎关注我的公众号前端历劫之路

回复关键词电子书,即可获取12本前端热门电子书。

回复关键词红宝书第4版,即可获取最新《JavaScript高级程序设计》(第四版)电子书。

关注公众号后,点击下方菜单即可加我微信,我拉拢了很多IT大佬,创建了一个*技术交流、文章分享群,期待你的加入。

作者:Vam的金豆之路

微信公众号:前端历劫之路

手把手教你用前端实现短视频App(滑动切换)

本文转转自微信公众号前端历劫之路原创https://mp.weixin.qq.com/s/hFrHxBDjn_l1-v7fhA0OyQ,如有侵权,请联系删除。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Stella981 Stella981
2年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Stella981 Stella981
2年前
Android So动态加载 优雅实现与原理分析
背景:漫品Android客户端集成适配转换功能(基于目标识别(So库35M)和人脸识别库(5M)),导致apk体积50M左右,为优化客户端体验,决定实现So文件动态加载.!(https://oscimg.oschina.net/oscnet/00d1ff90e4b34869664fef59e3ec3fdd20b.png)点击上方“蓝字”关注我
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这