项目题全解:音乐播放器—下-灵析社区

懒人学前端

Step 6:自动下一首的播放

基础知识:

@ended 事件:audio 原生的 ended 事件,实现自动播放下一首

基础操作:

第一步 :添加结束按钮

<audio :src="currentSrc" controls autoplay @ended='handleEnded'></audio>

第二步 :添加对应方法

handleEnded() {
         // 下一首的播放
        this.currentIndex++;
        this.currentSrc = this.musicData[this.currentIndex].songSrc;
 },

参考代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>音乐播放器</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        ul {
            list-style: none;
        }

        ul li {
            margin: 20px 20px;
            padding: 10px 5px;
            border-radius: 3px;
        }

        ul li.active {
            background-color: #D2E2F3;
        }
    </style>
</head>

<body>
    <div id='app'>
        <!-- 在这里添加基础html -->
        <audio :src="currentSrc" controls autoplay @ended='handleEnded'></audio>
        <ul>
            <li v-for='(item,index) in musicData' :key='item.id' @click="handleClick(item.songSrc,index)"
                :class='{active:index === currentIndex}'>
                第{{item.id}}首歌 歌曲:{{item.name}} 的</p>
                <p> 作者:{{item.author}} </p>
            </li>
        </ul>
    </div>

    <script src="./vue.js"></script>
    <script>
        // 基础数据
        const musicData = [{
            id: 1,
            name: '大眠-王心凌',
            author: '王心凌',
            songSrc: './static/大眠-王心凌.mp3'
        },
        {
            id: 2,
            name: '千千阙歌-陈慧娴',
            author: '陈慧娴',
            songSrc: './static/千千阙歌-陈慧娴.mp3'
        },
        {
            id: 3,
            name: '圣诞结-陈奕迅',
            author: '陈奕迅',
            songSrc: './static/圣诞结-陈奕迅.mp3'
        },
        {
            id: 4,
            name: '快乐崇拜-潘玮柏',
            author: '潘玮柏',
            songSrc: './static/快乐崇拜-潘玮柏.mp3'
        }
        ];

        new Vue({
            el: '#app',
            data: {
                musicData,
                currentSrc: './static/大眠-王心凌.mp3',
                currentIndex: 1,
            },
            methods: {
                handleClick(src, index) {
                    this.currentSrc = src;
                    this.currentIndex = index;
                },
                handleEnded() {
                    // 下一首的播放
                    this.currentIndex++;
                    if (this.currentIndex === this.musicData.length) {
                        this.currentIndex = 0;
                    }
                    this.currentSrc = this.musicData[this.currentIndex].songSrc;
                },
            }
        })
    </script>

</body>

</html>

Step 7:手动下一首的播放

基础知识:

绑定监听@click:(以监听click为例,其他如keyup,用法类似) v-on:click="fun" @click="fun" @click="fun(参数)"

基础操作:

第一步:

添加按钮样式

<button @click='handleNext'>下一首</button>

第二步:

添加按钮样点击事件

handleNext() {
    this.currentIndex++;
    // 到底了,重新归 0
    if (this.currentIndex === this.musicData.length) {
        this.currentIndex = 0;
    }
    this.currentSrc = this.musicData[this.currentIndex].songSrc
}

效果展示:

参考代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>音乐播放器</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        ul {
            list-style: none;
        }

        ul li {
            margin: 20px 20px;
            padding: 10px 5px;
            border-radius: 3px;
        }

        ul li.active {
            background-color: #D2E2F3;
        }
    </style>
</head>

<body>
    <div id='app'>
        <!-- 在这里添加基础html -->
        <audio :src="currentSrc" controls autoplay @ended='handleEnded'></audio>
        <ul>
            <li v-for='(item,index) in musicData' :key='item.id' @click="handleClick(item.songSrc,index)"
                :class='{active:index === currentIndex}'>
                第{{item.id}}首歌 歌曲:{{item.name}} 的</p>
                <p> 作者:{{item.author}} </p>
            </li>
        </ul>
        <button @click='handleNext'>下一首</button>
    </div>

    <script src="./vue.js"></script>
    <script>
        // 基础数据
        const musicData = [{
            id: 1,
            name: '大眠-王心凌',
            author: '王心凌',
            songSrc: './static/大眠-王心凌.mp3'
        },
        {
            id: 2,
            name: '千千阙歌-陈慧娴',
            author: '陈慧娴',
            songSrc: './static/千千阙歌-陈慧娴.mp3'
        },
        {
            id: 3,
            name: '圣诞结-陈奕迅',
            author: '陈奕迅',
            songSrc: './static/圣诞结-陈奕迅.mp3'
        },
        {
            id: 4,
            name: '快乐崇拜-潘玮柏',
            author: '潘玮柏',
            songSrc: './static/快乐崇拜-潘玮柏.mp3'
        }
        ];

        new Vue({
            el: '#app',
            data: {
                musicData,
                currentSrc: './static/大眠-王心凌.mp3',
                currentIndex: 1,
            },
            methods: {
                handleClick(src, index) {
                    this.currentSrc = src;
                    this.currentIndex = index;
                },
                handleEnded() {
                    // 下一首的播放
                    this.currentIndex++;
                    if (this.currentIndex === this.musicData.length) {
                        this.currentIndex = 0;
                    }
                    this.currentSrc = this.musicData[this.currentIndex].songSrc;
                },
                handleNext() {
                    this.currentIndex++;
                    // 到底了,重新归 0
                    if (this.currentIndex === this.musicData.length) {
                        this.currentIndex = 0;
                    }
                    this.currentSrc = this.musicData[this.currentIndex].songSrc
                }
            }
        })
    </script>

</body>

</html>

Step 8:代码更新,变得更简洁

基础操作:

第一步:代码复用

handleEnded() {
    // 下一首的播放
    // this.currentIndex++;
    // this.currentSrc = this.musicData[this.currentIndex].songSrc;
    handleNext();
},

参考代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>音乐播放器</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        ul {
            list-style: none;
        }

        ul li {
            margin: 20px 20px;
            padding: 10px 5px;
            border-radius: 3px;
        }

        ul li.active {
            background-color: #D2E2F3;
        }
    </style>
</head>

<body>
    <div id='app'>
        <!-- 在这里添加基础html -->
        <audio :src="currentSrc" controls autoplay @ended='handleEnded'></audio>
        <ul>
            <li v-for='(item,index) in musicData' :key='item.id' @click="handleClick(item.songSrc,index)"
                :class='{active:index === currentIndex}'>
                第{{item.id}}首歌 歌曲:{{item.name}} 的</p>
                <p> 作者:{{item.author}} </p>
            </li>
        </ul>
        <button @click='handleNext'>下一首</button>
    </div>

    <script src="./vue.js"></script>
    <script>
        // 基础数据
        const musicData = [{
            id: 1,
            name: '大眠-王心凌',
            author: '王心凌',
            songSrc: './static/大眠-王心凌.mp3'
        },
        {
            id: 2,
            name: '千千阙歌-陈慧娴',
            author: '陈慧娴',
            songSrc: './static/千千阙歌-陈慧娴.mp3'
        },
        {
            id: 3,
            name: '圣诞结-陈奕迅',
            author: '陈奕迅',
            songSrc: './static/圣诞结-陈奕迅.mp3'
        },
        {
            id: 4,
            name: '快乐崇拜-潘玮柏',
            author: '潘玮柏',
            songSrc: './static/快乐崇拜-潘玮柏.mp3'
        }
        ];

        new Vue({
            el: '#app',
            data: {
                musicData,
                currentSrc: './static/大眠-王心凌.mp3',
                currentIndex: 1,
            },
            methods: {
                handleClick(src, index) {
                    this.currentSrc = src;
                    this.currentIndex = index;
                },
                handleEnded() {
                    // 下一首的播放
                    // this.currentIndex++;
                    // if (this.currentIndex === this.musicData.length) {
                    //     this.currentIndex = 0;
                    // }
                    // this.currentSrc = this.musicData[this.currentIndex].songSrc;
                    handleNext();
                },
                handleNext() {
                    this.currentIndex++;
                    // 到底了,重新归 0
                    if (this.currentIndex === this.musicData.length) {
                        this.currentIndex = 0;
                    }
                    this.currentSrc = this.musicData[this.currentIndex].songSrc
                }
            }
        })
    </script>

</body>

</html>

Step 9:用 computed 更新代码方式

基础知识:

computed 用来监控自己定义的变量,该变量不在 data里面声明,

直接在 computed 里面定义,进行处理后返回一个结果值。

基础操作:

第一步:改变src属性

<audio :src="getCurrentSongSrc" controls autoplay @ended='handleEnded'></audio>

第二步:添加计算属性

// 计算属性
            computed: {
                getCurrentSongSrc() {
                    return this.musicData[this.currentIndex].songSrc;
                }
            },

第三步:更新方法

<li v-for='(item,index) in musicData' :key='item.id' @click="handleClick(index)"
    :class='{active:index === currentIndex}'>
    第{{item.id}}首歌 歌曲:{{item.name}} 的</p>
    <p> 作者:{{item.author}} </p>
</li>

...


handleClick(index) {
    this.currentIndex = index;
},
handleEnded() {
    this.handleNext();
},

参考代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>音乐播放器</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }

        ul {
            list-style: none;
        }

        ul li {
            margin: 20px 20px;
            padding: 10px 5px;
            border-radius: 3px;
        }

        ul li.active {
            background-color: #D2E2F3;
        }
    </style>
</head>

<body>
    <div id='app'>
        <!-- 在这里添加基础html -->
        <audio :src="getCurrentSongSrc" controls autoplay @ended='handleEnded'></audio>
        <ul>
            <li v-for='(item,index) in musicData' :key='item.id' @click="handleClick(index)"
                :class='{active:index === currentIndex}'>
                第{{item.id}}首歌 歌曲:{{item.name}} 的</p>
                <p> 作者:{{item.author}} </p>
            </li>
        </ul>
        <button @click='handleNext'>下一首</button>
    </div>

    <script src="./vue.js"></script>
    <script>
        // 基础数据
        const musicData = [{
            id: 1,
            name: '大眠-王心凌',
            author: '王心凌',
            songSrc: './static/大眠-王心凌.mp3'
        },
        {
            id: 2,
            name: '千千阙歌-陈慧娴',
            author: '陈慧娴',
            songSrc: './static/千千阙歌-陈慧娴.mp3'
        },
        {
            id: 3,
            name: '圣诞结-陈奕迅',
            author: '陈奕迅',
            songSrc: './static/圣诞结-陈奕迅.mp3'
        },
        {
            id: 4,
            name: '快乐崇拜-潘玮柏',
            author: '潘玮柏',
            songSrc: './static/快乐崇拜-潘玮柏.mp3'
        }
        ];

        new Vue({
            el: '#app',
            data: {
                musicData,
                currentIndex: 0,
            },
            // 计算属性
            computed: {
                getCurrentSongSrc() {
                    // 当currentIndex改变时,computed 会自动计算 currentIndex 对应的 currentSrc
                    return this.musicData[this.currentIndex].songSrc;
                }
            },
            methods: {
                handleClick(index) {
                    this.currentIndex = index;
                },
                handleEnded() {
                    this.handleNext();
                },
                handleNext() {
                    this.currentIndex++;
                    // 到底了,重新归 0
                    if (this.currentIndex === this.musicData.length) {
                        this.currentIndex = 0;
                    }
                }
            }
        })
    </script>

</body>

</html>

在这里是否可以使用 watch ?computed 和 watch 有什么区别?

computed 和 watch 的区别:

computed 支持缓存,相依赖的数据发生改变才会重新计算;watch 不支持缓存,只要监听的数据变化就会触发相应操作

computed 不支持异步,当 computed 内有异步操作时是无法监听数据变化的;watch 支持异步操作

computed 属性的属性值是一函数,函数返回值为属性的属性值,computed 中每个属性都可以设置 set 与 get 方法。watch 监听的数据必须是 data 中声明过或父组件传递过来的 props 中的数据,当数据变化时,触发监听器。

阅读量:435

点赞量:0

收藏量:0