vue2.0实现音乐/视频播放进度条组件

yizhihongxing

关于“vue2.0实现音乐/视频播放进度条组件”的攻略,我们需要考虑到以下几个方面:

  1. 组件设计
  2. 组件实现
  3. 组件使用

组件设计

在设计组件时,我们需要考虑以下几个方面:

  1. 组件的功能需求:播放进度条组件需要提供能够显示当前播放进度和总时长的功能,以及能够拖动改变播放进度的功能。
  2. 状态管理:我们需要维护当前播放时间、总时长和拖动状态的状态。
  3. 组件结构:播放进度条组件可以横向或竖向显示,我们可以考虑使用flex布局或absolute定位实现。

组件实现

在组件实现时,我们需要完成以下几个步骤:

  1. 组件结构设计:在template模板中使用 div、span、input等基本html元素构建组件结构。
  2. 数据管理:使用 props将播放的总时长和当前播放时间传入组件,通过data来定义组件需要维护的内部状态,包括播放开始时间、拖动状态和当前进度等值。
  3. 事件处理:使用 @mousedown、@mousemove、@mouseup和 @click 等事件处理函数,完成播放进度条拖动、重新开始播放等功能。
  4. 时长转换:处理组件接收到的时间单位,可以通过 Math.floor、PadStart 等API处理显示效果。

下面是一个基础示例:

<template>
  <div class="play-progress-bar">
    <span class="current-time">{{ currentTime }}</span>
    <input
      class="progress-bar"
      type="range"
      min="0"
      max="100"
      @mousedown="startDrag"
      @mousemove="dragging"
      @mouseup="stopDrag"
      @click="seekTo"
      :value="progress"
    />
    <span class="total-time">{{ totalTime }}</span>
  </div>
</template>

<script>
export default {
  name: "play-progress",
  props: {
    currentTime: Number, //当前播放时间
    totalTime: Number //总时长
  },
  data() {
    return {
      duration: 0, //播放开始时间
      dragging: false, //是否正在拖动
      progress: null //当前进度
    };
  },
  methods: {
    startDrag() {
      this.dragging = true;
      this.duration = this.currentTime;
    },
    dragging(evt) {
      if (!this.dragging) return;
      const target = evt.target;
      const rect = target.getBoundingClientRect();
      const offsetX = evt.clientX - rect.left;
      const progress = offsetX / target.offsetWidth;
      this.progress = progress;
    },
    stopDrag(evt) {
      if (!this.dragging) return;
      this.dragging = false;
      const target = evt.target;
      const rect = target.getBoundingClientRect();
      const offsetX = evt.clientX - rect.left;
      const progress = offsetX / target.offsetWidth;
      this.progress = progress;
      this.seekTo();
    },
    seekTo() {
      const time = this.progress * this.totalTime;
      this.$emit("change", time);
      this.duration = time;
    }
  },
  computed: {
    progress: {
      set(val) {
        if (!this.dragging) return;
        this.$emit("change", val * this.totalTime);
        this.duration = val * this.totalTime;
      },
      get() {
        return this.totalTime && this.currentTime
          ? (this.currentTime / this.totalTime) * 100
          : 0;
      }
    }
  }
};
</script>

<style scoped>
.play-progress-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 30px;
  background-color: #aaa;
  position: relative;
}
.progress-bar {
  width: 100%;
  height: 4px;
  -webkit-appearance: none;
  background-color: #333;
  outline: none;
  cursor: pointer;
  position: relative;
  z-index: 1;
}
.progress-bar::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #333;
  position: relative;
  z-index: 2;
}
.current-time,
.total-time {
  margin-left: 10px;
  margin-right: 10px;
  font-size: 12px;
  color: #333;
}
</style>

除此之外,我们还可以根据具体需求进行进一步的组件优化和功能拓展,例如对进度条进行美化、添加缓存等功能。

下面是一个进阶示例:

<template>
  <div class="play-progress-bar">
    <div class="progress-bar-wrap">
      <div class="progress-buffer-bar" :style="{ width: bufferedProgress + '%' }"></div>
      <div class="progress-point" :style="{ left: progress + '%' }">
        <span class="current-time">{{ currentTime | formatTime }}</span>
        <span class="point" @click="seekTo"></span>
      </div>
      <div class="progress-play-bar" :style="{ width: progress + '%' }"></div>
    </div>
    <span class="total-time">{{ totalTime | formatTime }}</span>
  </div>
</template>

<script>
export default {
  name: "play-progress",
  props: {
    currentTime: Number,
    totalTime: Number,
    bufferProgress: Number
  },
  filters: {
    formatTime(value) {
      if (!value) return "00:00";

      let minute = Math.floor(value / 60);
      let second = Math.floor(value % 60);

      minute = minute < 10 ? "0" + minute : minute;
      second = second < 10 ? "0" + second : second;

      return `${minute}:${second}`;
    }
  },
  computed: {
    progress() {
      if (this.totalTime === 0) {
        return 0;
      } else {
        return (this.currentTime / this.totalTime) * 100;
      }
    },
    bufferedProgress() {
      if (this.totalTime === 0) {
        return 0;
      } else {
        return (this.bufferProgress / this.totalTime) * 100;
      }
    }
  },
  methods: {
    seekTo(evt) {
      evt.stopPropagation();
      const target = evt.target;
      const rect = target.getBoundingClientRect();
      const offsetX = evt.clientX - rect.left;
      const progress = offsetX / target.offsetWidth;
      this.$emit("seekto", progress);
    }
  }
};
</script>

<style scoped>
.play-progress-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  height: 30px;
  background-color: #aaa;
  padding: 0 10px;
  position: relative;
}
.progress-bar-wrap {
  width: 100%;
  height: 4px;
  background-color: #ddd;
  cursor: pointer;
  position: relative;
}
.progress-buffer-bar {
  background-color: #666;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 0;
}
.progress-play-bar {
  background-color: #333;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
  z-index: 1;
}
.progress-point {
  position: absolute;
  top: -14px;
  left: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
}
.progress-point .current-time {
  display: inline-block;
  height: 16px;
  line-height: 16px;
  font-size: 12px;
  padding: 0 6px;
  margin-right: 8px;
  border-radius: 2px;
  background-color: #666;
  color: #fff;
}
.progress-point .point {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background-color: #333;
  cursor: pointer;
}
.total-time {
  font-size: 12px;
  color: #333;
}
</style>

在这个示例中,我们添加了缓冲进度条,支持点击缓冲区间快速跳转到指定播放位置,并添加了时间格式化Filter等功能。

组件使用

在实际使用我们的播放进度条组件时,我们只需要将组件引用在需要播放的组件中,并传递相应的参数即可。例如:

<template>
  <section>
    <h2>MUSIC</h2>
    <audio src="./music.mp3" ref="audio" @timeupdate="updateTime" @progress="updateBuffer"></audio>
    <play-progress
      :current-time="currentTime"
      :total-time="totalTime"
      :buffer-progress="bufferProgress"
      @seekto="handleSeekTo"
    />
  </section>
</template>

<script>
import PlayProgress from "./PlayProgress";

export default {
  name: "Music",
  components: {
    PlayProgress
  },
  data() {
    return {
      currentTime: 0,
      totalTime: 0,
      bufferProgress: 0
    };
  },
  methods: {
    updateTime(evt) {
      this.currentTime = evt.target.currentTime;
      this.totalTime = evt.target.duration;
    },
    updateBuffer(evt) {
      if (evt.target.buffered.length) {
        this.bufferProgress = evt.target.buffered.end(0);
      }
    },
    handleSeekTo(progress) {
      const time = progress * this.totalTime;
      this.$refs.audio.currentTime = time;
    }
  }
};
</script>

<style>
h2 {
  font-size: 24px;
  font-weight: bold;
  margin-bottom: 10px;
}
</style>

在这个示例中,我们在一个Music组件中引用了播放进度条组件,使用Audio元素播放音频,并通过$refs获取Audio组件实例,获取当前播放进度和总时长、缓冲进度并传递给播放进度条组件。当播放进度条组件发生变化时,我们通过@seekto事件处理函数和$refs获取的Audio组件实例来更新播放进度和总时长。

以上便是solidot教程中“vue2.0实现音乐/视频播放进度条组件”的完整攻略。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:vue2.0实现音乐/视频播放进度条组件 - Python技术站

(0)
上一篇 2023年5月29日
下一篇 2023年5月29日

相关文章

  • 深入理解Vuex的作用

    深入理解Vuex的作用 什么是Vuex? Vuex 是一个专门为 Vue.js 设计的状态管理库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 在一个典型的 Vue 应用中,组件之间的通信是通过 props 和事件进行的,这样简单的场景并没有问题,但是在大型的应用中,状态的管理会变得非常复杂。每一个子组件都需要…

    Vue 2023年5月28日
    00
  • vue-element-admin 全局loading加载等待

    Vue-Element-Admin 是一个基于 Vue.js 的前端管理系统框架,该框架支持全局loading加载等待功能,可以有效提升用户体验。下面将介绍如何在 Vue-Element-Admin 中使用全局loading加载等待功能的完整攻略。 添加全局loading组件 首先,在 src/layout/components/AppMain.vue 文件…

    Vue 2023年5月28日
    00
  • 详解Vue-Router的安装与使用

    下面就是“详解Vue-Router的安装与使用”的完整攻略。 1. 什么是Vue-Router Vue-Router是Vue.js官方推荐的路由管理库,它能够方便地管理Vue.js应用程序中的导航和路由。 路由(Routing)是指根据不同的URL地址展现不同的内容或页面。通过Vue-Router,我们能够实现在单页应用中切换不同的页面而不用刷新整个页面。 …

    Vue 2023年5月27日
    00
  • Vue3项目中引用TS语法的实例讲解

    引入 TypeScript 是 Vue3 项目中的一种常见选择,它有助于提高代码质量和开发效率。下面将提供一个完整的指南,帮助你在 Vue3 项目中引入 TypeScript。 第一步:安装依赖 在 Vue3 项目中使用 TypeScript,首先需要安装一些必要的依赖。在项目根目录下,运行以下命令: npm install –save-dev types…

    Vue 2023年5月27日
    00
  • VSCode搭建vue项目的实现步骤

    下面我将详细讲解 “VSCode搭建vue项目的实现步骤”的完整攻略。整个过程包括: 安装Node.js 安装Vue CLI 创建Vue项目 配置VSCode开发环境 运行Vue项目 示例说明 1. 安装Node.js 首先,需要在电脑上安装Node.js,以便在命令行终端中使用npm安装Vue CLI和其他必要依赖项。Node.js的官方安装包可以在官网下…

    Vue 2023年5月28日
    00
  • vue前端RSA加密java后端解密的方法实现

    要实现前端Vue使用RSA加密数据,后端Java进行解密的过程,需要完成以下步骤: 1.在前端Vue中引入RSA库 在前端Vue中,可以使用jsencrypt这个RSA库来实现加密。可以使用npm安装: npm install jsencrypt 然后,在Vue组件中引入: import JSEncrypt from ‘jsencrypt’ 2.在前端Vue…

    Vue 2023年5月28日
    00
  • vue中的scope使用详解

    Vue中的Scope使用详解 在Vue中,我们可以通过在模板中使用v-for指令来遍历数据,然后使用v-bind或简写方式:将数据传递给子组件。但是,有时候我们需要将数据传递到子组件中,而不需要在父级模板中显示这些数据。为了实现这一点,Vue提供了scope属性,这可以让我们创建一个只传递特定数据子组件的插槽。 父组件和子组件之间使用Scope 假设我们有以…

    Vue 2023年5月27日
    00
  • 使用Webpack 搭建 Vue3 开发环境过程详解

    使用Webpack搭建Vue3开发环境的过程可以分为以下几个步骤: 1.安装Webpack和Vue3依赖 在开始使用Webpack搭建Vue3开发环境之前,我们需要先安装Webpack和Vue3的相关依赖。 Webpack是一个打包工具,可以将多个JavaScript、CSS、HTML等文件打包成一个或多个JavaScript文件。在搭建Vue3开发环境时,…

    Vue 2023年5月28日
    00
合作推广
合作推广
分享本页
返回顶部