• 从零开始利用vue-cli搭建简单音乐网站(七)


    这几天完成了歌曲收藏功能,先看最后效果:

    新注册用户:“newuser”,进入“我的音乐界面如下所示”

    点击新建歌单,输入:“新歌单”,确认,如下:

    目前还没有歌曲,打开音乐界面,点击收藏功能,如下,可以看到新创建的歌单已经在上面:

    把歌曲收藏在新歌单,在打开我的音乐界面,已经收藏好了:

    点击删除之后,可以看到歌曲已经被删除:

    删除歌单:

    基本的功能就是这样,有一些细节就不展示了,下面是实现,整体功能的实现,跟前面没太大区别,利用vue-resource和后台通信,发送请求,在后台利用mongoose操作数据库,实现数据的增删查改,返回数据,动态更新。

    1、在音乐播放界面(src//Components/PlayMusic.vue)创建歌单集合

     发送请求到后台获得歌单列表:

    openCollectSong: function() {
                    // 打开新建歌单界面
                    this.isCollect = true
                    var Data = {
                        username: this.PlayMusicMsg.username
                    }
                    this.$http.post("/query/querySongs", Data).then(function(response) {
                        if(response.body.errno === 0) {
                            this.songs = response.body.data
                        }
                    })
                },

    这里没有利用弹窗处理弹出界面,而是利用v-show绑定isCollect,判断是否显示歌单列表。接着把Data对象利用post发送给后台,最后获得response数据赋值给歌单列表songs,相应的后台请求如下:

    // 查找歌单
    queryRoutes.post('/querySongs', function(req, res) {
        var username = req.body.username
        songListModel.find({
            username: username
        }, function(error, data) {
            res.send({
                errno: 0,
                data: data
            })
        })
    })

    利用songListModel.find({username:username},function(){})方法,第一个参数username是从post过来的req中取得的,表示查找相应username下的所有歌单列表,然后返回列表数组。

    2、用户点击新建歌单,获得输入名称并创建歌单,如果歌单名称已经存在则创建失败

    下面是请求代码以及后台代码:

    createNewSong: function() {
                    var songlist = prompt("请输入新歌单名:")
                    if(songlist != null) {
                        var songlistData = {
                            username: this.PlayMusicMsg.username,
                            name: songlist
                        }
                        this.$http.post("/query/InsertSong", songlistData).then(function(response) {
                            //更新歌单
                            if(response.body.errno === 0){
                            var Data = {
                                username: this.PlayMusicMsg.username
                            }
                            this.$http.post("/query/querySongs", Data).then(function(response) {
                                if(response.body.errno === 0) {
                                    this.songs = response.body.data
                                }
                            })
                            } else {
                                alert("歌单已存在")
                            }
                        })
                    }
                }

    prompt弹出输入框让用户输入新歌单名称,获得之后把歌单名称,用户姓名统一成对象发送到后台数据库,然后更新界面。

    后台处理请求:

    // 插入新歌单
    queryRoutes.post("/InsertSong", function(req, res) {
    
        var name = req.body.name
    
        // 如果歌单名称存在,则不插入
        songListModel.find({
            name: name
        }, function(error, data) {
            console.log(data)
            if(data[0] == null) {
                // 为空说明歌单名称还没有创建
                var songListEntity = new songListModel({
                    name: name,
                    username: req.body.username
                })
                songListEntity.save(function(error, data) {
                    if(error) {
                        res.send({
                            errno: 1,
                            data: "创建错误"
                        })
                    } else {
                        res.send({
                            errno: 0,
                            data: "成功"
                        })
                    }
                })
            } else {
                res.send({
                    errno: 2,
                    data: "歌单已经存在"
                })
            }
        })
    })

    如上,利用songListModel.find({})判断歌单是否存在,存在则返回errno=2,否则就插入并且返回errno=0。

    3、用户把歌曲收藏在歌单

    这里歌单界面用到一个新组件collectSong.vue,该组件就是收藏歌单界面实体,用户点击歌单之后,会把用户名,当前歌曲名称,歌单名称传送过来,这里涉及父子组件的数据传输,用props接收,具体代码如下:

    CollectSong.vue界面:

    export default {
            name: "CollectSong",
            data() {
                return {}
            },
            props: {
                PlayMusicData: {
              // 该对象数组用于显示歌单姓名,其实上述的歌单列表都是传递到该组件显示
    default: null }, CurrentMusicData: {
              // 当前音乐名称
    default: null }, PlayMusicMsg: {           用户名 } }, ... }

    PlayMusic.vue界面传递数据:

            <CollectSong :PlayMusicData="songs" :CurrentMusicData="music" :PlayMusicMsg='PlayMusicMsg'></CollectSong>

    有了数据之后,CollectSong界面再把相应歌曲存进数据库:

    addMusic: function(e) {
                    // 根据传过来的事件判断点击的li标签,并且把当前页面歌曲传递给歌单
                    // 把当前歌曲名称拿出来,歌单名称拿出来,创建为一个对象,保存在数据库"collectMusic"集合
                    var username = this.PlayMusicMsg.username
                    var selectSong = e.target.innerHTML
                    var musicName = this.CurrentMusicData.name
    
                    var collectMusicData = {
                        username: username,
                        selectSong: selectSong,
                        musicName: musicName
                    }
    
                    this.$http.post("/query/InsertMusic", collectMusicData).then(function(response) {
                        if(response.body.errno === 0) {
                            alert("保存成功")
                            this.close()
                        } else {
                            alert("歌曲已经在歌单中")
                        }
                    })
                }

    上面先是创建了一个CollectMusicData实体,接着利用post请求发送到后台,如果返回errno=0则成功,否则表示歌曲已经存在歌单中,输出错误提示。

    最后是后台这边接收请求:

    // 往collectMusic集合插入数据
    queryRoutes.post('/InsertMusic', function(req, res) {
        var username = req.body.username
        var selectSong = req.body.selectSong
        var musicName = req.body.musicName
    
        collectMusicModel.find({
            username: username,
            selectSong: selectSong,
            musicName: musicName
        }, function(error, data) {
            // 如果歌曲已经存在歌单中则不插入
            if(data[0] == null) {
                var collectMusicEntity = new collectMusicModel({
                    username: username,
                    musicName: musicName,
                    selectSong: selectSong
                })
                collectMusicEntity.save(function(error, data) {
                    if(error) {
                        res.send({
                            errno: 1
                        })
                    } else {
                        res.send({
                            errno: 0
                        })
                    }
                })
            } else {
                res.send({
                    errno: 2
                })
            }
        })
    
    })

    跟插入歌单是一样的操作,显示根据传过来的username,selectSong和MusicName,利用find方法查找数据库有没有,没有的话创建CollectMusicEntity并且把数据插入数据库。

    4、MyMusic.vue界面实现

    这个界面的实现,跟上面显示歌单列表是一样的请求,这里不多展示了。还有一点就是歌单以及歌曲的删除,也是利用post请求,把相应的请求信息发送给后台,后台利用remove方法删除相应数据。具体实现如下:

    MyMusic.vue界面发送删除歌曲请求:

    <span id="deleteMusic" v-show="index === music_i" @click="deleteMusic" :title="music.name">删除</span>
    
    // 对应绑定方法如下
    deleteMusic: function(e) {
                    // 根据歌名找到在musics数组的位置,利用方法删除,然后更新数据库
                    var key,
                        nowname = e.target.title // 歌名
    
                    for(key in this.musics) {
                        if(this.musics[key].name === nowname) {
                            this.musics.splice(key, 1)
                            break
                        }
                    }
                    var collectMusicData = {
                        username: this.MyMusicMsg.username,
                        musicName: nowname,
                        selectSong: this.nowSong
                    }
    
                    this.$http.post('/query/delMusic', collectMusicData).then(function(response) {
                        // 删除成功,musicCount数组更新
                        this.nowMusicCount--;
                        this.musicCount[key]--
                    })
                },

    用户点击删除按钮时候触发方法,之后创建实体,利用post请求发送数据,后台接受如下:

    // 往collectMusic集合删除数据
    queryRoutes.post('/delMusic', function(req, res) {
        var username = req.body.username
        var musicName = req.body.musicName
        var selectSong = req.body.selectSong
        
        if(musicName != undefined) {
            collectMusicModel.remove({
                username: username,
                musicName: musicName,
                selectSong: selectSong
            }, function(error, data) {
                res.send({
                    errno: 0,
                    data: data
                })
            })
        } else {
            collectMusicModel.remove({
                username: username,
                selectSong: selectSong
            }, function(error, data) {
                res.send({
                    errno: 0,
                    data: data
                })
            })
        }
    })

    利用remove删除相应数据。

    后面歌单删除跟这个一样原理,不赘述。只是要注意一点,当用户删除歌单时候,歌单所对应的歌曲也要从数据库清空。

    至此,历时十天,音乐网站的雏形已经完成,只是我个人也知道网站还有很多的不足,包括性能优化,兼容,代码优化等等,这只是我个人练习的一个小课题,很多方面可能写出来的博客不够全面,后面如果有时间应该会对该网站再次优化的,感谢阅读。

    以上。

  • 相关阅读:
    python 模拟(简易)音乐播放器
    Python中的多态如何理解?(转)
    mysql踩得坑
    python简单模拟博客园系统
    04 信号量
    02 事件
    01 管道
    32 管道 事件 信号量 进程池 线程的创建
    02 验证进程之间是空间隔离的
    01 进程的其他方法
  • 原文地址:https://www.cnblogs.com/oujiamin/p/7787541.html
Copyright © 2020-2023  润新知