参考:

https://www.bilibili.com/video/BV12J411m7MG

 

github 下载完整项目:

https://github.com/VicentWYS/Vue_MusicPlayer

 

核心:

Vue + axios 联合使用,axios用于发起get请求,从接口获取数据。

Vue框架使用,对从接口返回的数据(类似于DOM树的集合)进行选择,然后渲染到页面上。

 

 

项目启动方法:

1.启动IDEA

2.打开项目 – 已存在的项目

3.选择项目文件夹,点击确定

 

效果:

播放器页面:

 

 

 MV播放页面:

 

 

 

vueMusicPlayer.html:

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 
 4 <head>
 5     <meta charset="UTF-8" />
 6     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 7     <meta http-equiv="X-UA-Compatible" content="ie=edge" />
 8     <title>悦听player</title>
 9     <!-- 样式 -->
10     <link rel="stylesheet" href="./css/index.css">
11 </head>
12 
13 <body>
14 <div class="wrap">
15     <!-- 播放器主体区域 -->
16     <div class="play_wrap" id="player">
17         <div class="search_bar">
18             <img src="images/player_title.png" alt="" />
19             <!-- 搜索歌曲 -->
20             <input type="text" autocomplete="off" v-model="query" @keyup.enter="searchMusic" />
21         </div>
22         <div class="center_con">
23             <!-- 搜索歌曲列表 -->
24             <div class=\'song_wrapper\'>
25                 <ul class="song_list">
26                     <li v-for="item in musicList">
27                         <a href="javascript:;" @click="playMusic(item.id)"></a>
28                         <b>{{item.name}}</b>
29                         <span v-if="item.mvid!=0" @click="playMV(item.mvid)"><i></i></span>
30                     </li>
31                 </ul>
32                 <img src="images/line.png" class="switch_btn" alt="">
33             </div>
34             <!-- 歌曲信息容器 -->
35             <div class="player_con" :class="{playing:isPlaying}">
36                 <img src="images/player_bar.png" class="play_bar" />
37                 <!-- 黑胶碟片 -->
38                 <img src="images/disc.png" class="disc autoRotate" />
39                 <img class="cover autoRotate" :src="musicCover" />
40             </div>
41             <!-- 评论容器 -->
42             <div class="comment_wrapper">
43                 <h5 class=\'title\'>热门留言</h5>
44                 <div class=\'comment_list\'>
45                     <dl v-for="item in hotComments">
46                         <dt><img :src="item.user.avatarUrl" alt=""></dt>
47                         <dd class="name">{{item.user.nickname}}</dd>
48                         <dd class="detail">{{item.content}}</dd>
49                     </dl>
50                 </div>
51                 <img src="images/line.png" class="right_line">
52             </div>
53         </div>
54         <!--播放面板-->
55         <div class="audio_con">
56             <audio ref=\'audio\' @play="play" @pause="pause" :src="musicUrl" controls autoplay loop class="myaudio"></audio>
57         </div>
58         <div class="video_con" v-show="isShow" style="display: none;">
59             <video :src="mvUrl" controls="controls"></video>
60             <div class="mask" @click="hide"></div>
61         </div>
62     </div>
63 </div>
64 <!-- 开发环境版本,包含了有帮助的命令行警告 -->
65 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
66 <!-- 官网提供的 axios 在线地址 -->
67 <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
68 <script src="./js/main.js"></script>
69 </body>
70 
71 </html>

View Code

 

main.js:

  1 /*
  2 歌曲搜索接口:
  3 请求地址:https://autumnfish.cn/search
  4 请求方法:get
  5 请求参数:keywords(查询关键字)
  6 响应内容:歌曲搜索结果
  7 */
  8 
  9 /*
 10 歌曲url获取接口
 11 请求地址:https://autumnfish.cn/song/url
 12 请求方法:get
 13 请求参数:id(查询关键字)
 14 响应内容:歌曲url地址
 15  */
 16 
 17 /*
 18 歌曲详情获取
 19 请求地址:https://autumnfish.cn/song/detail
 20 请求方法:get
 21 请求参数:ids(歌曲id)
 22 响应内容:歌曲详情(包括封面信息)
 23  */
 24 
 25 /*
 26 热门评论获取
 27 请求地址:https://autumnfish.cn/comment/hot?type=0
 28 请求方法:get
 29 请求参数:id(歌曲id,地址中的type固定为0)
 30 响应内容:歌曲的热门评论
 31  */
 32 
 33 /*
 34 mv地址获取
 35     请求地址:https://autumnfish.cn/mv/url
 36     请求方法:get
 37     请求参数:id(mvid,为0表示没有mv)
 38     响应内容:mv的地址
 39  */
 40 
 41 var app = new Vue({
 42     el:\'#player\',
 43     data:{
 44         // 查询关键字
 45         query:"",
 46         // 歌曲数组
 47         musicList:[],
 48         // 歌曲地址
 49         musicUrl:"",
 50         // 歌曲封面
 51         musicCover:"",
 52         // 歌曲评论
 53         hotComments:[],
 54         // 动画播放状态
 55         isPlaying:false,
 56         // 遮罩层的显示状态
 57         isShow:false,
 58         // mv地址
 59         mvUrl:""
 60     },
 61     methods:{
 62         // 歌曲搜索
 63         searchMusic:function () {
 64             var that = this;
 65             axios.get("https://autumnfish.cn/search?keywords=" + this.query)
 66                 .then(function (res) {
 67                     // console.log(res);
 68                     that.musicList = res.data.result.songs;
 69                 }, function (err) {
 70                 })
 71         },
 72         // 歌曲播放
 73         playMusic:function (musicId) {
 74             var that = this;
 75             // 获取歌曲地址
 76             axios.get("https://autumnfish.cn/song/url?id=" + musicId)
 77                 .then(function (res) {
 78                     that.musicUrl = res.data.data[0].url;
 79                 }, function (err) {});
 80 
 81             // 歌曲详情获取
 82             axios.get("https://autumnfish.cn/song/detail?ids=" + musicId)
 83                 .then(
 84                     function (res) {
 85                         // console.log(res);
 86                         // console.log(res.data.songs[0].al.picUrl);
 87                         that.musicCover = res.data.songs[0].al.picUrl;
 88                     }, function (err) {  }
 89                 );
 90 
 91             // 歌曲评论获取
 92             axios.get("https://autumnfish.cn/comment/hot?type=0&id=" + musicId)
 93                 .then(
 94                     function (res) {
 95                         // console.log(res);
 96                         // console.log(res.data.hotComments);
 97                         that.hotComments = res.data.hotComments;
 98                     }, function (err) {  }
 99                 )
100 
101         },
102         // 歌曲播放
103         play:function () {
104             // console.log("play");
105             this.isPlaying = true;
106         },
107         // 歌曲暂停
108         pause:function () {
109             // console.log("pause");
110             this.isPlaying = false;
111         },
112         // 播放mv
113         playMV:function (mvid) {
114             var that = this;
115             // 获取MV地址
116             axios.get("https://autumnfish.cn/mv/url?id=" + mvid)
117                 .then(function (res) {
118                     // console.log(res.data.data.url);
119                     // 显示遮罩层
120                     that.isShow = true;
121                     that.mvUrl = res.data.data.url;
122                 }, function (err) {});
123         },
124         //隐藏遮罩层
125         hide:function () {
126             this.isShow = false;
127         }
128     }
129 });

View Code

 

index.css:

  1 body,
  2 ul,
  3 dl,
  4 dd {
  5   margin: 0px;
  6   padding: 0px;
  7 }
  8 
  9 .wrap {
 10   position: fixed;
 11   left: 0;
 12   top: 0;
 13   width: 100%;
 14   height: 100%;
 15   background: url("../images/bg.jpg") no-repeat;
 16   background-size: 100% 100%;
 17 }
 18 
 19 .play_wrap {
 20   width: 800px;
 21   height: 544px;
 22   position: fixed;
 23   left: 50%;
 24   top: 50%;
 25   margin-left: -400px;
 26   margin-top: -272px;
 27   /* background-color: #f9f9f9; */
 28 }
 29 
 30 .search_bar {
 31   height: 60px;
 32   background-color: #1eacda;
 33   border-top-left-radius: 4px;
 34   border-top-right-radius: 4px;
 35   display: flex;
 36   align-items: center;
 37   justify-content: space-between;
 38   position: relative;
 39   z-index: 11;
 40 }
 41 
 42 .search_bar img {
 43   margin-left: 23px;
 44 }
 45 
 46 .search_bar input {
 47   margin-right: 23px;
 48   width: 296px;
 49   height: 34px;
 50   border-radius: 17px;
 51   border: 0px;
 52   background: url("../images/zoom.png") 265px center no-repeat
 53     rgba(255, 255, 255, 0.45);
 54   text-indent: 15px;
 55   outline: none;
 56 }
 57 
 58 .center_con {
 59   height: 435px;
 60   background-color: rgba(255, 255, 255, 0.5);
 61   display: flex;
 62   position: relative;
 63 }
 64 
 65 .song_wrapper {
 66   width: 200px;
 67   height: 435px;
 68   box-sizing: border-box;
 69   padding: 10px;
 70   list-style: none;
 71   position: absolute;
 72   left: 0px;
 73   top: 0px;
 74   z-index: 1;
 75 }
 76 
 77 .song_stretch {
 78   width: 600px;
 79 }
 80 
 81 .song_list {
 82   width: 100%;
 83   overflow-y: auto;
 84   overflow-x: hidden;
 85   height: 100%;
 86 }
 87 .song_list::-webkit-scrollbar {
 88   display: none;
 89 }
 90 
 91 .song_list li {
 92   font-size: 12px;
 93   color: #333;
 94   height: 40px;
 95   display: flex;
 96   flex-wrap: wrap;
 97   align-items: center;
 98   width: 580px;
 99   padding-left: 10px;
100 }
101 
102 .song_list li:nth-child(odd) {
103   background-color: rgba(240, 240, 240, 0.3);
104 }
105 
106 .song_list li a {
107   display: block;
108   width: 17px;
109   height: 17px;
110   background-image: url("../images/play.png");
111   background-size: 100%;
112   margin-right: 5px;
113   box-sizing: border-box;
114 }
115 
116 .song_list li b {
117   font-weight: normal;
118   width: 122px;
119   overflow: hidden;
120   text-overflow: ellipsis;
121   white-space: nowrap;
122 }
123 
124 .song_stretch .song_list li b {
125   width: 200px;
126 }
127 
128 .song_stretch .song_list li em {
129   width: 150px;
130 }
131 
132 .song_list li span {
133   width: 23px;
134   height: 17px;
135   margin-right: 50px;
136 }
137 .song_list li span i {
138   display: block;
139   width: 100%;
140   height: 100%;
141   cursor: pointer;
142   background: url("../images/table.png") left -48px no-repeat;
143 }
144 
145 .song_list li em,
146 .song_list li i {
147   font-style: normal;
148   width: 100px;
149 }
150 
151 .player_con {
152   width: 400px;
153   height: 435px;
154   position: absolute;
155   left: 200px;
156   top: 0px;
157 }
158 
159 .player_con2 {
160   width: 400px;
161   height: 435px;
162   position: absolute;
163   left: 200px;
164   top: 0px;
165 }
166 
167 .player_con2 video {
168   position: absolute;
169   left: 20px;
170   top: 30px;
171   width: 355px;
172   height: 265px;
173 }
174 
175 .disc {
176   position: absolute;
177   left: 73px;
178   top: 60px;
179   z-index: 9;
180 }
181 .cover {
182   position: absolute;
183   left: 125px;
184   top: 112px;
185   width: 150px;
186   height: 150px;
187   border-radius: 75px;
188   z-index: 8;
189 }
190 .comment_wrapper {
191   width: 180px;
192   height: 435px;
193   list-style: none;
194   position: absolute;
195   left: 600px;
196   top: 0px;
197   padding: 25px 10px;
198 }
199 .comment_wrapper .title {
200   position: absolute;
201   top: 0;
202   margin-top: 10px;
203 }
204 .comment_wrapper .comment_list {
205   overflow: auto;
206   height: 410px;
207 }
208 .comment_wrapper .comment_list::-webkit-scrollbar {
209   display: none;
210 }
211 .comment_wrapper dl {
212   padding-top: 10px;
213   padding-left: 55px;
214   position: relative;
215   margin-bottom: 20px;
216 }
217 
218 .comment_wrapper dt {
219   position: absolute;
220   left: 4px;
221   top: 10px;
222 }
223 
224 .comment_wrapper dt img {
225   width: 40px;
226   height: 40px;
227   border-radius: 20px;
228 }
229 
230 .comment_wrapper dd {
231   font-size: 12px;
232 }
233 
234 .comment_wrapper .name {
235   font-weight: bold;
236   color: #333;
237   padding-top: 5px;
238 }
239 
240 .comment_wrapper .detail {
241   color: #666;
242   margin-top: 5px;
243   line-height: 18px;
244 }
245 .audio_con {
246   height: 50px;
247   background-color: #f1f3f4;
248   border-bottom-left-radius: 4px;
249   border-bottom-right-radius: 4px;
250 }
251 .myaudio {
252   width: 800px;
253   height: 40px;
254   margin-top: 5px;
255   outline: none;
256   background-color: #f1f3f4;
257 }
258 /* 旋转的动画 */
259 @keyframes Rotate {
260   from {
261     transform: rotateZ(0);
262   }
263   to {
264     transform: rotateZ(360deg);
265   }
266 }
267 /* 旋转的类名 */
268 .autoRotate {
269   animation-name: Rotate;
270   animation-iteration-count: infinite;
271   animation-play-state: paused;
272   animation-timing-function: linear;
273   animation-duration: 5s;
274 }
275 /* 是否正在播放 */
276 .player_con.playing .disc,
277 .player_con.playing .cover {
278   animation-play-state: running;
279 }
280 
281 .play_bar {
282   position: absolute;
283   left: 200px;
284   top: -10px;
285   z-index: 10;
286   transform: rotate(-25deg);
287   transform-origin: 12px 12px;
288   transition: 1s;
289 }
290 /* 播放杆 转回去 */
291 .player_con.playing .play_bar {
292   transform: rotate(0);
293 }
294 /* 搜索历史列表 */
295 .search_history {
296   position: absolute;
297   width: 296px;
298   overflow: hidden;
299   background-color: rgba(255, 255, 255, 0.3);
300   list-style: none;
301   right: 23px;
302   top: 50px;
303   box-sizing: border-box;
304   padding: 10px 20px;
305   border-radius: 17px;
306 }
307 .search_history li {
308   line-height: 24px;
309   font-size: 12px;
310   cursor: pointer;
311 }
312 .switch_btn {
313   position: absolute;
314   right: 0;
315   top: 0;
316   cursor: pointer;
317 }
318 .right_line {
319   position: absolute;
320   left: 0;
321   top: 0;
322 }
323 .video_con video {
324   position: fixed;
325   width: 800px;
326   height: 546px;
327   left: 50%;
328   top: 50%;
329   margin-top: -273px;
330   transform: translateX(-50%);
331   z-index: 990;
332 }
333 .video_con .mask {
334   position: fixed;
335   width: 100%;
336   height: 100%;
337   left: 0;
338   top: 0;
339   z-index: 980;
340   background-color: rgba(0, 0, 0, 0.8);
341 }
342 .video_con .shutoff {
343   position: fixed;
344   width: 40px;
345   height: 40px;
346   background: url("../images/shutoff.png") no-repeat;
347   left: 50%;
348   margin-left: 400px;
349   margin-top: -273px;
350   top: 50%;
351   z-index: 995;
352 }

View Code

 

版权声明:本文为CPU-Easy原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/CPU-Easy/p/14519517.html