vue自定义音频样式

594 阅读1分钟

封装自己的组件 Audio.vue。基于JQ来获取dom

<template>
  <div class="Audio">
    <audio id="audioTag" :src="audioSrc"></audio>
    <div class="audiocon">
      <!-- 按钮 -->
      <div class="leftBtn">
        <div class="play">
          <img @click="bofang" :src="require(`@/assets/img/goods/${isPlay ? 'audio1' : 'audio2'}.png`)" alt="" />
        </div>
      </div>
      <div class="adcon">
        <div class="bar">
          <div class="activeLine" @click="seekTime">
            <div :style="{ width: currentPosi + '%' }" class="dot"></div>
          </div>
        </div>
        <div class="time">
          <span>{{ time }}</span><span>&nbsp;/&nbsp;{{ allTime }}</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Audio",
  props: {
    audioSrc: {
      type: String,
    },
  },
  data() {
    return {
      active: 0,
      time: 0,
      _audio: "",
      isPlay: this.isMobile,
      currentPosi: 0,
      allTime: 0,
    };
  },
  methods: {
    bofang() {
      if (this._audio.paused) {
        this._audio.play();
        this.isPlay = true;
      } else {
        this._audio.pause();
        this.isPlay = false;
      }
    },
    transTime(time) {
      var duration = parseInt(time);
      var minute = parseInt(duration / 60);
      var sec = (duration % 60) + "";
      var isM0 = ":";
      if (minute == 0) {
        minute = "00";
      } else if (minute < 10) {
        minute = "0" + minute;
      }
      if (sec.length == 1) {
        sec = "0" + sec;
      }
      return minute + isM0 + sec;
    },
    updateProgress() {
      this.currentPosi = (this._audio.currentTime / this._audio.duration) * 100;
      this.time = this.transTime(this._audio.currentTime);
    },

    audioEnded() {
      this._audio.currentTime = 0;
      this._audio.pause();
      this.isPlay = false;
    },

    seekTime(e) {
      var rate = e.offsetX / e.target.clientWidth;
      this._audio.currentTime = this._audio.duration * rate;
      this.updateProgress();
    },
  },
  mounted() {
    this.$nextTick(() => {
      this._audio = $(`#audioTag`)[0];
      $(`#audioTag`).on("loadedmetadata", (e) => {
        this.time = this.isMobile
          ? "00:00"
          : this.transTime(e.currentTarget.duration);
        this.allTime = this.transTime(e.currentTarget.duration);
        this._audio.play();
        this.isPlay = true;
      });

      document.addEventListener(
        "WeixinJSBridgeReady",
        function () {
          this._audio.play();
        },
        false
      );

      $(`#audioTag`).on("timeupdate", () => {
        this.updateProgress();
      });

      $(`#audioTag`).on("timeupdate", () => {
        this.updateProgress();
      });

      $(`#audioTag`).on("ended", () => {
        this.audioEnded();
      });
    });
  },
  activated() {
    this.isPlay = this.isMobile;
  },
};
</script>

<style lang="less" scoped>
.Audio {
  width: 100%;
  height: 100%;
  padding: 0 15px;

  .audiocon {
    display: flex;
    align-items: center;
    width: 100%;
    height: 100%;
    justify-content: space-between;
  }

  .leftBtn {
    width: 30px;

    img {
      width: 100%;
    }
  }

  .adcon {
    position: relative;
    z-index: 10;
    width: calc(100% - 46px);
    height: 100%;
    display: flex;
    align-items: center;

    .bar {
      width: calc(100% - 80px);
      position: relative;
      height: 100%;
      display: flex;
      align-items: center;

      .activeLine {
        position: absolute;
        top: 0;
        left: 0px;
        z-index: 10;
        width: 96%;
        height: 100%;
        cursor: pointer;

        &::before {
          content: "";
          position: absolute;
          width: 100%;
          height: 4px;
          top: 50%;
          left: 0;
          transform: translateY(-50%);
          border-radius: 4px;

          background-color: #FFB199;
        }
      }

      .dot {
        border-radius: 4px;
        z-index: 11;
        pointer-events: none;
        position: absolute;
        height: 4px;
        top: 50%;
        left: 0px;
        transform: translateY(-50%);
        background-color: #FF615C;

        &::before {
          content: "";
          position: absolute;
          top: -3px;
          right: -3px;
          width: 10px;
          height: 10px;
          border-radius: 50%;
          background-color: #FF615C;
        }
      }
    }

    .time {
      width: 80px;
      font-size: 14px;
      color: #999999;
      display: flex;
    }
  }
}
</style>

使用:

//导入和注册
import Audio from "./Audio.vue";
export default {
  components: { Audio },

//模板中使用
                <Audio
                    :audioSrc=""
                 />