音乐播放器实战

实现效果

image-20210816154212109

  1. 在搜索框中搜索歌曲,可以点击“搜索”按钮或者摁下回车键开始搜索
  2. 返回的结果会在左边显示,点击“播放”按钮开始播放,有MV的歌曲将会显示“播放MV”的按钮
  3. 选择一首歌曲开始播放时,右边会出现该歌曲的热门评论,有评论者的id,头像和内容
  4. 音乐在播放时,歌曲封面会360度转动,点击暂停后,封面也会停止

项目准备

音乐数据的axios接口:

image-20210815210939103 image-20210815215325493 image-20210815222226715 image-20210816105734659 image-20210816142744229

使用axios返回response数据时,可以先使用console.log(response)在控制台打印输出,需要在页面展示的数据可以在如下对象中获取,比如:

获取歌曲名:

image-20210815212844944

获取音乐地址:

image-20210815220129740

代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>音乐播放器</title>
    <style>
        li {
            list-style: none;
        }

        .main {
            float: left;
            width: 600px;
            margin: 0 auto;
            text-align: center;
            position: relative;
            left: 400px;
        }

        .reviews {
            float: right;
            width: 400px;
        }

        .right {
            float: left;
            width: 400px;
            position: relative;
            right: 400px;
        }

        .playing {
            transform: rotate(360deg);
            animation: rotation 20s linear infinite;
        }

        @keyframes rotation {
            from {
                transform: rotate(0deg);
            }
            to {
                transform: rotate(360deg);
            }
        }

        .mv {
            width: 800px;
            height: 450px;
            position: absolute;
            left: 367.5px;
            top: 167px;
        }
    </style>
</head>

<body>
<div id="app">
    <div class="main">
        <h1>音乐播放器</h1>
        请输入你查询的歌手或者歌曲:<input type="text" v-model="name" @keyup.enter="getSongs">
        <button @click="getSongs()">搜索</button>
        <br><br>
        (搜索慢,请稍等两秒)
        <br> <br>
        <audio v-bind:src="url" controls autoplay @play="play" @pause="pause"></audio>
        <br> <br> <br> <br> <br>
        <img v-bind:src="imageUrl" width="300px" height="300px"
             style="border-radius: 50%" :class="{playing:isplaying}">
    </div>

    <div class="right">
        <p>音乐列表</p>
        <ul>
            <li v-for="item in songList">
                {{item.name}}
                <button @click="getSing(item.id)">播放</button>
                <button @click="getMv(item.mvid)" v-if="item.mvid!==0">播放MV</button>
            </li>
        </ul>
    </div>
    <div class="mv" v-if="isshow">
        <video :src="mvUrl" controls width="800px" height="450px"></video>
    </div>

    <ul class="reviews">
        <p>热门评论:</p>
        <li v-for="review in reviewList">
            <img v-bind:src="review.user.avatarUrl" width="20px" height="20px">
            {{review.user.nickname}}:{{review.content}}
        </li>
    </ul>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="http://unpkg.com/axios/dist/axios.min.js"></script>

<script>
    var vm = new Vue({
        el: "#app",
        data: {
            name: "",
            songList: [],
            url: "",
            imageUrl: "",
            reviewList: [],
            isplaying: "",
            mvUrl: "",
            isshow: false
        },
        methods: {
            //获得歌曲的名字
            getSongs: function () {
                //回调函数需要使用that来传递this
                let that = this;
                axios.get("https://autumnfish.cn/search?keywords=" + this.name)
                    .then(function (response) {
                        that.songList = response.data.result.songs;
                    }, function (error) {
                        console.log(error)
                    });
            },
            //获得歌曲的在线url地址
            getSing: function (id) {
                let that = this;
                axios.get("https://autumnfish.cn/song/url?id=" + id)
                    .then(function (response) {
                        //注意返回的是数据数组,需要data[0]
                        that.url = response.data.data[0].url;
                    }, function (error) {
                        console.log(error);
                    })
                this.getImage(id);
                this.getReviews(id);
            },
            //获取歌曲封面
            getImage: function (id) {
                let that = this;
                axios.get("https://autumnfish.cn/song/detail?ids=" + id)
                    .then(function (response) {
                        that.imageUrl = response.data.songs[0].al.picUrl;
                    }, function (error) {
                        console.log(error);
                    })
            },
            //获取歌曲评论
            getReviews: function (id) {
                let that = this;
                axios.get("https://autumnfish.cn/comment/hot?type=0&id=" + id)
                    .then(function (response) {
                        that.reviewList = response.data.hotComments;
                    }, function (error) {
                        console.log(error);
                    })
            },
            //控制封面旋转
            play: function () {
                this.isplaying = true;
            },
            pause: function () {
                this.isplaying = false;
            },
            //获取MV
            getMv: function (id) {
                let that = this;
                axios.get("https://autumnfish.cn/mv/url?id=" + id)
                    .then(function (response) {
                        that.isshow = true;
                        that.mvUrl = response.data.data.url;
                    }, function (error) {
                        console.log(error);
                    });

            }
        }
    });
</script>
</body>
</html>

注意点

  1. 在函数中赋值给data数据时,不要忘记加上this
  2. 在回调函数中不要忘记定义that来传递this
  3. 注意response返回的是对象还是数组,数组需要加上data[0]
  4. 给img属性赋值时,要使用v-bind:src=""来进行属性绑定,而不是用<img src="{{xxx}}">
  5. audio音频监听播放和暂停可以使用@play和@pause方法
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐