我做了一个网易云音乐外链播放器的Vue组件,很nice

话不多说,上视频:
https://www.bilibili.com/video/BV1p44y1M7KC/

介绍

起因是我的一个小项目用到了网易云音乐的外链播放器;于是将它从项目里剥离出来做成一个Vue组件;并开源献给网友们。

它能使外链播放器很优雅的浮动在页面上,支持鼠标和触摸屏拖动、自动贴边;不占空间支持收缩/展开。
细节方面做的很漂亮,配合Vue可以实现全站无刷新音乐播放功能。
需要的朋友拿走,有能力的小伙伴可以尝试将它与VuePress配合服用;一个更优雅的博客就诞生了。
具体长什么样子这里就来张图吧,其他的看视频
我做了一个网易云音乐外链播放器的Vue组件,很nice_第1张图片

使用

依赖:它需要使用npm安装jquery和ElementUI;这两个可以单独引入这个组件文件(jquery我已经引入好了;只需要再引入ElementUI)
使用方面:上代码
这是demo,在App.vue引入时的代码,当然也可以在其他任何Vue页面引入该组件。

<template>
  <div id="app">
  
    <NeteaseCloudPlayForVue url="//music.163.com/outchain/player?type=2&id=1817694137&auto=1&height=66"/>
  div>
template>

<script>
//引入组件文件
import NeteaseCloudPlayForVue from './components/NeteaseCloudPlayForvue.vue'

export default {
  name: 'App',
  //禁用 Attribute 继承
  inheritAttrs: false,
  //组件注册
  components: {
    NeteaseCloudPlayForVue
  },
}
script>

组件代码:

<template>
  <div>
    <div
        v-bind:class="NeteaseCloudPlayIframeClass"
        v-bind:style="NeteaseCloudPlayIframeStyle"
        @mousedown="NeteaseCloudPlayIframeMouseDownOrUp =  true"
        @mouseup="NeteaseCloudPlayIframeMouseDownOrUp = false"
        @touchend="NeteaseCloudPlayIframeMouseDownOrUp = false"
        @touchstart="NeteaseCloudPlayIframeMouseDownOrUp =  true"
        @touchmove.prevent.stop="NeteaseCloudPlayIframeForTouchClick($event)"
    >
      <el-row>
        <el-col :span="NeteaseIconSpan">
          <div
              v-bind:class="NeteaseCloudPlayIframeClassIcon"
              @mousedown="NeteaseShowClick"
              @mouseup="NeteaseIconUp = true"
          >
            <el-row>
              <el-col :pull="4" :span="1">
                <i v-bind:class="NeteaseIconClass">i>
              el-col>
            el-row>
          div>
        el-col>
        <el-col :span="23">
          <div
              v-bind:class="NeteaseCloudPlayIframeDivClass"
              v-bind:style="NeteaseCloudPlayIframeDivStyle"
          >
            <iframe
                border="0"
                frameborder="no"
                height="86"
                marginheight="0"
                marginwidth="0"
                v-bind:src="url"
                v-bind:style="NeteaseCloudPlayIframeIframeStyle"
                width="280"
            >iframe>
          div>
        el-col>
      el-row>
    div>
  div>
template>

<script>
import $ from "jquery";
//此处可以单独引入ElementUI,如果你的项目不需要全局引入的话
export default {
  name: 'NeteaseCloudPlayForVue',
  props: {
    url: String
  },
  data() {
    return {
      NeteaseCloudPlayIframeClass: "NeteaseCloudPlayIframe",
      NeteaseCloudPlayIframeStyle: "left:60px;top:40%;",
      NeteaseCloudPlayIframeMouseDownOrUp: false,
      NeteaseCloudPlayIframeClassIcon: "NeteaseCloudPlayIframeIcon",
      NeteaseCloudPlayIframeDivStyle: "left:-270px;",
      NeteaseCloudPlayIframeWindowWidth: 0,
      NeteaseIconSpan: 1,
      NeteaseIconClass: "el-icon-arrow-left",
      NeteaseCloudPlayIframeDivClass: "NeteaseCloudPlayIframeDiv",
      NeteaseGPSLeftOrRight: true,
      NeteaseGPSTop: 0,
      NeteaseGPSLeft: 0,
      NeteaseIfMove: false,
      NeteaseIconUp: false,
      NeteaseLockIframeIframeStyle: true,
      NeteaseCloudPlayIframeIframeStyle:
          "mask-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0) 100%, rgba(0, 0, 0, 1) 0%);",
    };
  },
  methods: {
    NeteaseCloudPlayIframeClick(event) {
      var e = event || window.event;
      var ValueX = e.pageX || e.clientX + document.body.scroolLeft;
      var ValueY = e.pageY || e.clientY + document.body.scrollTop;
      var x = ValueX - 10;
      var y = ValueY - 45;
      if (this.NeteaseCloudPlayIframeMouseDownOrUp == true) {
        if (this.NeteaseCloudPlayIframeClass != "NeteaseCloudPlayIframe") {
          this.NeteaseCloudPlayIframeClass = "NeteaseCloudPlayIframe";
        }
        var HalfWindowWidth = this.NeteaseCloudPlayIframeWindowWidth / 2;
        var ToCenterLong = ValueX - HalfWindowWidth;
        if (ToCenterLong > 0) {
          this.NeteaseCloudPlayIframeStyle =
              "left:" + x + "px;" + "top:" + y + "px;";
          this.NeteaseGPSLeft = x;
          this.NeteaseGPSTop = y;
          if (ToCenterLong < 270) {
            if (this.NeteaseGPSLeftOrRight != false) {
              this.NeteaseIconFlipClick();
              this.NeteaseGPSLeftOrRight = false;
              if (this.NeteaseLockIframeIframeStyle == false) {
                this.NeteaseCloudPlayIframeDivClass =
                    "NeteaseCloudPlayIframeDiv NeteaseCloudPlayIframeTransition";
                this.NeteaseCloudPlayIframeDivStyle = "left:-270px;";
              } else {
                this.NeteaseCloudPlayIframeDivClass =
                    "NeteaseCloudPlayIframeDiv";
                this.NeteaseCloudPlayIframeDivStyle = "left:0px;";
              }
            }
          }
        } else {
          this.NeteaseCloudPlayIframeStyle =
              "left:" + x + "px;" + "top:" + y + "px;";
          this.NeteaseGPSLeft = x;
          this.NeteaseGPSTop = y;
          if (HalfWindowWidth - ValueX < 270) {
            if (this.NeteaseGPSLeftOrRight != true) {
              this.NeteaseIconFlipClick();
              this.NeteaseGPSLeftOrRight = true;
              if (this.NeteaseLockIframeIframeStyle == false) {
                this.NeteaseCloudPlayIframeDivClass =
                    "NeteaseCloudPlayIframeDiv NeteaseCloudPlayIframeTransition";
                this.NeteaseCloudPlayIframeDivStyle = "left:0px;";
              } else {
                this.NeteaseCloudPlayIframeDivClass =
                    "NeteaseCloudPlayIframeDiv";
                this.NeteaseCloudPlayIframeDivStyle = "left:-270px;";
              }
            }
          }
        }
        this.NeteaseIfMove = true;
      }
    },
    NeteaseCloudPlayIframeForTouchClick(event) {
      var ValueX = event.targetTouches[0].clientX;
      var ValueY = event.targetTouches[0].clientY;
      var x = ValueX - 10;
      var y = ValueY - 45;
      if (this.NeteaseCloudPlayIframeMouseDownOrUp == true) {
        if (this.NeteaseCloudPlayIframeClass != "NeteaseCloudPlayIframe") {
          this.NeteaseCloudPlayIframeClass = "NeteaseCloudPlayIframe";
        }
        var HalfWindowWidth = this.NeteaseCloudPlayIframeWindowWidth / 2;
        var ToCenterLong = ValueX - HalfWindowWidth;
        if (ToCenterLong > 0) {
          this.NeteaseCloudPlayIframeStyle =
              "left:" + x + "px;" + "top:" + y + "px;";
          this.NeteaseGPSLeft = x;
          this.NeteaseGPSTop = y;
          if (ToCenterLong < 270) {
            if (this.NeteaseGPSLeftOrRight != false) {
              this.NeteaseIconFlipClick();
              this.NeteaseGPSLeftOrRight = false;
              if (this.NeteaseLockIframeIframeStyle == false) {
                this.NeteaseCloudPlayIframeDivClass =
                    "NeteaseCloudPlayIframeDiv NeteaseCloudPlayIframeTransition";
                this.NeteaseCloudPlayIframeDivStyle = "left:-270px;";
              } else {
                this.NeteaseCloudPlayIframeDivClass =
                    "NeteaseCloudPlayIframeDiv";
                this.NeteaseCloudPlayIframeDivStyle = "left:0px;";
              }
            }
          }
        } else {
          this.NeteaseCloudPlayIframeStyle =
              "left:" + x + "px;" + "top:" + y + "px;";
          this.NeteaseGPSLeft = x;
          this.NeteaseGPSTop = y;
          if (HalfWindowWidth - ValueX < 270) {
            if (this.NeteaseGPSLeftOrRight != true) {
              this.NeteaseIconFlipClick();
              this.NeteaseGPSLeftOrRight = true;
              if (this.NeteaseLockIframeIframeStyle == false) {
                this.NeteaseCloudPlayIframeDivClass =
                    "NeteaseCloudPlayIframeDiv NeteaseCloudPlayIframeTransition";
                this.NeteaseCloudPlayIframeDivStyle = "left:0px;";
              } else {
                this.NeteaseCloudPlayIframeDivClass =
                    "NeteaseCloudPlayIframeDiv";
                this.NeteaseCloudPlayIframeDivStyle = "left:-270px;";
              }
            }
          }
        }
        this.NeteaseIfMove = true;
      }
    },
    NeteaseCloudPlayIframeWindowWidthClick() {
      this.NeteaseCloudPlayIframeWindowWidth = $(window).width();
    },
    NeteaseIconFlipClick() {
      if (this.NeteaseIconClass == "el-icon-arrow-left") {
        this.NeteaseIconClass = "el-icon-arrow-right";
      } else {
        this.NeteaseIconClass = "el-icon-arrow-left";
      }
    },
    NeteaseHelpToEdge() {
      if (this.NeteaseCloudPlayIframeMouseDownOrUp == false) {
        if (this.NeteaseIfMove == true) {
          if (
              this.NeteaseCloudPlayIframeClass !=
              "NeteaseCloudPlayIframe NeteaseCloudPlayIframeTransition"
          ) {
            this.NeteaseCloudPlayIframeClass =
                "NeteaseCloudPlayIframe NeteaseCloudPlayIframeTransition";
          }
          if (this.NeteaseGPSLeftOrRight == true) {
            this.NeteaseCloudPlayIframeStyle =
                "left:" + 60 + "px;" + "top:" + this.NeteaseGPSTop + "px;";
          } else {
            this.NeteaseCloudPlayIframeStyle =
                "left:" +
                (this.NeteaseCloudPlayIframeWindowWidth - 80) +
                "px;" +
                "top:" +
                this.NeteaseGPSTop +
                "px;";
          }
        }
      }
    },
    NeteaseShowClick() {
      this.NeteaseIconUp = false;
      setTimeout(() => {
        if (this.NeteaseIconUp == true) {
          this.NeteaseCloudPlayIframeDivClass =
              "NeteaseCloudPlayIframeDiv NeteaseCloudPlayIframeDivTransition";
          let i;
          let x;
          let Show;
          let NotShow;
          if (this.NeteaseGPSLeftOrRight == true) {
            if (this.NeteaseCloudPlayIframeDivStyle != "left:-270px;") {
              this.NeteaseIconFlipClick();
              this.NeteaseLockIframeIframeStyle = true;
              this.NeteaseCloudPlayIframeDivStyle = "left:-270px;";
              i = 0;
              NotShow = setInterval(() => {
                i++;
                x = i + 20;
                if (i == 100) {
                  x = 100;
                }
                this.NeteaseCloudPlayIframeIframeStyle =
                    "mask-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0) " +
                    i +
                    "%, rgba(0, 0, 0, 1) " +
                    x +
                    "%);";
                if (i == 100) {
                  clearInterval(NotShow);
                }
              }, 10);
            } else {
              this.NeteaseIconFlipClick();
              this.NeteaseLockIframeIframeStyle = false;
              this.NeteaseCloudPlayIframeDivStyle = "left:0px;";
              i = 100;
              Show = setInterval(() => {
                i--;
                x = i + 20;
                if (i == 0) {
                  x = 0;
                }
                this.NeteaseCloudPlayIframeIframeStyle =
                    "mask-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0) " +
                    i +
                    "%, rgba(0, 0, 0, 1) " +
                    x +
                    "%);";
                if (i == 0) {
                  clearInterval(Show);
                }
              }, 10);
            }
          } else {
            if (this.NeteaseCloudPlayIframeDivStyle != "left:0px;") {
              this.NeteaseIconFlipClick();
              this.NeteaseLockIframeIframeStyle = true;
              this.NeteaseCloudPlayIframeDivStyle = "left:0px;";
              i = 0;
              NotShow = setInterval(() => {
                i++;
                x = i + 20;
                if (i == 100) {
                  x = 100;
                }
                this.NeteaseCloudPlayIframeIframeStyle =
                    "mask-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0) " +
                    i +
                    "%, rgba(0, 0, 0, 1) " +
                    x +
                    "%);";
                if (i == 100) {
                  clearInterval(NotShow);
                }
              }, 10);
            } else {
              this.NeteaseIconFlipClick();
              this.NeteaseLockIframeIframeStyle = false;
              this.NeteaseCloudPlayIframeDivStyle = "left:-270px;";
              i = 100;
              Show = setInterval(() => {
                i--;
                x = i + 20;
                if (i == 0) {
                  x = 0;
                }
                this.NeteaseCloudPlayIframeIframeStyle =
                    "mask-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0) " +
                    i +
                    "%, rgba(0, 0, 0, 1) " +
                    x +
                    "%);";
                if (i == 0) {
                  clearInterval(Show);
                }
              }, 10);
            }
          }
        }
      }, 200);
    },
  },
  mounted() {
    $(() => {
      $(window).mousemove(this.NeteaseCloudPlayIframeClick);
      this.NeteaseCloudPlayIframeWindowWidthClick();
      $(window).resize(this.NeteaseCloudPlayIframeWindowWidthClick);
      $(window).mouseup(this.NeteaseHelpToEdge);
      $(window).on("touchend", this.NeteaseHelpToEdge);
    });
  }
}
script>
<style scoped>
.NeteaseCloudPlayIframe {
  position: fixed;
  width: 0;
}

.NeteaseCloudPlayIframeIcon {
  user-select: none;
  top: 10px;
  position: absolute;
  height: 66px;
  width: 18px;
  background-color: #dcdfe6;
  z-index: 1;
}

.NeteaseCloudPlayIframeDiv {
  position: relative;
}

.NeteaseCloudPlayIframeIcon i {
  position: absolute;
  top: 22px;
  font-size: 25px;
  color: #606266;
}

.NeteaseCloudPlayIframeTransition {
  transition: all 1s ease;
}

.NeteaseCloudPlayIframeDivTransition {
  transition: all 1s linear;
}
style>

代码没加多少注释哈,我认为命名已经很明确了。
感谢你看到我的文章,希望能帮到你。
请添加图片描述

你可能感兴趣的:(vue,前端,音频,个人开发)