从零开始利用vue-cli搭建简单音乐网站(八)
这是完成了预想中的最后两个功能:歌曲评论以及歌曲搜索。
1、评论效果:
用户点击评论按钮,评论框获取焦点。
输入之后点击提交,下方显示评论,用户名称以及日期。相应的用户也可以删除自己评论。
当然只能删除自己的评论,鼠标放置其他人评论上面不会显示删除按钮。
2、搜索歌曲
搜索可以搜索歌曲或者歌手,这里搜索"LiSA",结果如下:
也可以只输入“A”,显示如下:
这里有一个歌手页面,显示的是所有歌手的歌曲,如点击"Aimer"歌手:
至此,基本功能就展示完成,下面看实现。
先是评论功能,在评论按钮监听点击事件:“<button class="btn" @click="focusToComment">评论</button>”
focusToComment事件,id=comment就是评论输入框:
focusToComment: function() {
// 点击跳转评论
document.getElementById("comment").focus()
},
然后是输入框提交按钮监听事件:“<input type="button" id="submitBtn" name="submitBtn" value="评论" @click="submitComment" />”
submitComment事件提交所输入的评论,实现如下:
submitComment: function() { if(this.PlayMusicMsg.username == "") {
alert("请先登录")
} else {
// 这里把评论,用户名,评论日期作为一个对象,然后和歌曲名称一起作为对象传递给后台
var message = this.message
var username = this.PlayMusicMsg.username // 这里获取当前时间
var date = new Date()
var year = date.getFullYear()
var month = date.getMonth() + 1
var day = date.getDate()
var commentDate = year + "年" + month + "月" + day + "日" var musicName = this.music.name var commentObj = {
message: message,
username: username,
commentDate: commentDate,
pos: 0
}
var commentData = {
musicName: musicName,
commentObj: commentObj
} // 发送请求
this.$http.post('/query/insertMusicComment', commentData).then(function(response) {
if(response.body.errno === 0) {
// 成功,更新界面
var newpos = response.body.data
var commentObj = {
message: message,
username: username,
commentDate: commentDate,
pos: newpos
}
this.comments.push(commentObj)
alert("评论成功")
}
})
}
},
先是利用App.vue页面传递过来的PlayMusicMsg参数检测用户名是否存在,不存在表示还没有登录,所以提示先登录。然后登陆的话,把用户名username,评论message,评论日期Date封装为commentObj对象,注意该对象还有一个pos,表示评论位置,这是我实现评论删除的思路,因为每一首歌曲下面只有一个评论数组,所以后面只需要找到对应pos的评论就可以从数据库去除。接着把commentObj对象和歌曲名musicName封装在一起发送给后台,成功的话用this.comments.push(commentObj)把评论显示在页面上。
接着是后台处理评论数据,如下:
// 插入歌曲评论
queryRoutes.post('/insertMusicComment', function(req, res) {
var musicName = req.body.musicName
var commentObj = req.body.commentObj musicCommentModel.find({
musicName: musicName
}, function(error, data) {
console.log(data)
if(data[0] != null) {
// 数据存在,更新
// 这里给每个评论添加一个序号
var length = data[0].comments.length
var pos;
if(length === 0) {
pos = 1
} else {
var last = data[0].comments.length - 1
pos = data[0].comments[last].pos + 1
}
commentObj.pos = pos
data[0].comments.push(commentObj) musicCommentModel.update({
musicName: musicName
}, {
comments: data[0].comments
}, function(error, data) {
res.send({
errno: 0,
data: pos
})
})
} else {
// 数据不存在,插入
var comments = []
commentObj.pos = 1
comments.push(commentObj)
var musicCommentEntity = new musicCommentModel({
musicName: musicName,
comments: comments
})
musicCommentEntity.save({}, function(error, data) {
res.send({
errno: 0,
data: pos
})
})
}
})
})
先获取到musicName和commentObj,利用find方法查找musicName是否存在,存在则更新数据。先获取该musicName下的评论数组的长度length,如果length=0,则pos设置为1,也就是将要插入的评论的序号,这也是为了将来删除所用。如果length不等于0那么pos等于评论数组最后一位的pos+1。接着利用data[0].comments.push(commentObj)把评论插入数组最后,最后利用update方法更新数据库。另一种情况,如果查找的musicName不存在的时候,pos设置为1,评论插入新数组comments.push(commentObj),新建musicCommentEntity实体,用其save方法保存到数据库。
下面是删除功能,在PlayMusic.vue页面,监听每一个评论项<li @mouseenter="show(index,value.username)" @mouseleave="hide" id="each-comment">,show方法显示“删除评论“字样,hide隐藏。实现如下:
<!--这里是删除评论元素绑定-->
<span v-show="index === i" @click="delComment(value.pos)" id="del-comment">删除评论</span> show: function(index, username) {
// 显示删除按钮,但是先判断当前用户名和评论用户名是否相等
if(this.PlayMusicMsg.username === username) {
this.i = index
}
},
hide: function() {
// 隐藏删除按钮
this.i = -1
},
这里的删除元素处绑定的是v-show="index===i",因为这是在一个v-for循环中,index是循环序号,i默认值为-1,当show事件触发的时候,把所有i赋值为index,也就是触发show事件的元素所在的序号,那么自然只有该元素的index才等于i,也就会显示出”删除按钮“了,具体可以参考博客:https://segmentfault.com/q/1010000005160077
这里用户点击删除按钮时候触发delComment事件,事件传递一个参数value.pos,也就是我上面保存时候所说的pos,这里的pos和数据库中的是一一对应的。delComment事件实现如下:
delComment: function(pos) { // 删除评论
var delCommentData = {
musicName: this.music.name,
pos: pos
}
this.$http.post('/query/delComment', delCommentData).then(function(response) {
if(response.body.errno === 0) {
// 删除成功,更新界面
var comments = this.comments
console.log(comments)
for(var key in comments) {
if(comments[key].pos === pos) {
comments.splice(key, 1)
break
}
}
this.comments = comments
}
})
}
实现很简单,封装delCommentData对象,musicName和pos,发送请求,成功的话界面也更新,更新思路是利用pos找到删除评论所在位置,用splice方法删除,更新。接着是后台接收请求然后实现的代码:
// 删除歌曲评论
queryRoutes.post('/delComment', function(req, res) {
var musicName = req.body.musicName
var pos = req.body.pos musicCommentModel.find({
musicName: musicName
}, function(error, data) {
var comments = data[0].comments
for(var key in comments) {
if(comments[key].pos === pos) {
comments.splice(key, 1)
break
}
}
musicCommentModel.update({
musicName: musicName
}, {
comments: comments
}, function(error, data) {
res.send({
errno: 0,
data: data
})
}) })
})
后台的思路其实是一样的,根据pos找到序号,删除,再用update更新。
评论功能之后,是歌曲搜索功能。实现思路是利用了mongoose的模糊搜索,匹配一个正则表达式对象,如果数据包含所匹配的字符串则返回,如下:
// 关键词搜索音乐
queryRoutes.post('/search', function(req, res) {
var searchStr = req.body.str
var reg = new RegExp(searchStr)
// 关键词索引
musicDataModel.find({
$or: [{
name: reg
}, {
singer: reg
}]
}, function(error, data) {
res.send({
errno: 0,
data: data
})
})
})
以上就是搜索的全部实现要点了,注意musicDataModel.find()方法里面的$or,这是mongoose提供的选择查找,属性值是一个数组,这里我分别查找了name和singer两个数据,也就是根据关键词匹配歌曲名称或者匹配歌手,参考链接:https://segmentfault.com/a/1190000008161345
然后返回前台,前台接收到数据更新在页面。关于前台有一点要提的就是,我是在App.vue的导航条处设置的搜索栏,这里用户点击确定后路由会渲染新组件SearchResult.vue,此时App会把用户输入数据发送给该子组件,具体实现如下:
search: function(e) {
if(e.keyCode === 13) {
// 跳转到搜索结果页面,把数据发送过去
this.$router.push({
name: 'SearchResult',
query: {
str: this.searchStr
}
})
this.$router.go(0)
}
}
SearchResult.vue组件接收数据:”this.str = this.$route.query.str“
上面是用了路由的query参数,我要说的问题就是,当用户第一次搜索的时候跳转很成功,但是如果在SearchResult搜索结果页面再次在搜索框输入数据之后,是必须刷新一次页面的数据才会更新,不然会完全没有反应,也就是search函数继续执行,但是str就是不更新。所以注意上面我写的this.$router.go(0),这是路由跳转函数,go(0)就表示跳转到浏览器历史纪录中的当前地址,全局路由一定要设置mode:history,否则会出错。
下面实现的就是歌手页面,也没有什么特别的技术,就不赘述了。以上
从零开始利用vue-cli搭建简单音乐网站(八)的更多相关文章
- 从零开始利用vue-cli搭建简单音乐网站(一)
最近在学习vue框架,练习了一些例子之后,想着搭建一个vue项目,了解到官方有提供一个vue-cli工具来搭建项目脚手架,尝试了一下,写下博客来记录一下. 一.工具环境 1.node.js 6.10. ...
- 从零开始利用vue-cli搭建简单音乐网站(七)
这几天完成了歌曲收藏功能,先看最后效果: 新注册用户:“newuser”,进入“我的音乐界面如下所示” 点击新建歌单,输入:“新歌单”,确认,如下: 目前还没有歌曲,打开音乐界面,点击收藏功能,如下, ...
- 从零开始利用vue-cli搭建简单音乐网站(六)
上一篇遗漏了一个简单的效果没写,见下图: 主页面点击热门推荐和更多之后跳转到歌曲列表页面,现在的页面只是简单的把所有歌曲列出来,没有进行排序.实现起来也很简单,在MainPage的两个链接上添加: & ...
- 从零开始利用vue-cli搭建简单音乐网站(五)
上一篇文章讲到的是如何利用mongoose从数据库读取数据然后更新页面,接下来要实现的就是用户注册登录功能,这个功能涉及到的东西太多了,今天只实现了登录功能,登陆之后更新导航条界面,最后效果如下: 登 ...
- 从零开始利用vue-cli搭建简单音乐网站(二)
1.利用vue-router实现页面跳转 程序可以正常运行之后,下面我们需要配置路由实现页面的局部刷新,这一功能将用来实现网站页面的跳转. 打开程序目录,进入"src\router\inde ...
- 从零开始利用vue-cli搭建简单音乐网站(四)
上一篇文章中说到这一篇博客会实现音乐播放功能,只是令我意外的是,如果利用h5的audio标签,几行代码就实现了......先来看一下最终效果吧. 这里直接用了audio标签,样式没有怎么管,能获得音乐 ...
- 从零开始利用vue-cli搭建简单音乐网站(三)
1.利用router-link在组件之间传递数据 如上图,MainPage.vue中主要有8个推荐曲目数据,主要实现方式是建立好主页面模板,然后用v-for循环获取返回的music对象,然后分别绑定曲 ...
- vue cli搭建项目及文件引入
cli搭建方法:需安装nodejs先 1.npm install -g cnpm --registry=https://registry.npm.taobao.org //安装cnpm,用cnpm下载 ...
- Koa2+MySQL+VUE+ElementIUI搭建简单的后台管理小系统
如题,前端入坑许久,还是写个小东西出来吧 想要搭建自己的一个后台管理,实现简单的增删改查,看起来很简单 其实是真的简单,没有想的那么难,我也就写了一个月吧, 当然是假的,其实也就每天一两个小时,花了大 ...
随机推荐
- 「HNOI2004」「LuoguP2292」L语言(AC自动机
题目描述 标点符号的出现晚于文字的出现,所以以前的语言都是没有标点的.现在你要处理的就是一段没有标点的文章. 一段文章T是由若干小写字母构成.一个单词W也是由若干小写字母构成.一个字典D是若干个单词的 ...
- Excel的poi缓存问题
Excel的poi缓存问题 背景: 最近工作需要,需要完成生成新的Excel,然后从Excel中读取包含公式的文本内容. 问题: 当程序中修改公式对应的单元格数据变化时,公式获取的值仍然还是原来的值, ...
- httpclient:实现有验证码的模拟登陆
//1.这种方式是先把验证码的图片下载到本地.并且根据网页解析获得token值//2.手动在控制台输入验证码//3.因为验证码图片已经下载下来,后面就可以使用图像文字识别package DoubanS ...
- 2.13 Hive中自带Function使用及自定义UDF编程
UDF:User Definition Function 一.function #查看自带的函数 hive (db_hive)> show functions; #查看一个函数的详细用法 hiv ...
- TypeScript完全解读(26课时)_12.TypeScript完全解读-高级类型(1)
12.TypeScript完全解读-高级类型(1) 高级类型中文网的地址:https://typescript.bootcss.com/advanced-types.html 创建新的测试文件 ind ...
- 接口开发之PHP创建XML文件
用PHP的DOM控件来创建输出 输出的格式为XML 接口开发的相关文件及说明 <?php header("Content-type: text/xml");//头文件非常重要 ...
- SourceTree配置BeyondCompare代码冲突解决工具
一.工具准备:SourceTree这个你得有.然后下载BeyondCompare(破解教程) 二.配置环境:SourceTree->工具->选项->比较,外部对比工具和合并工具都选择 ...
- Weekly Contest 78-------->809. Expressive Words (stack)
Sometimes people repeat letters to represent extra feeling, such as "hello" -> "he ...
- Codevs 3409 搬运礼物
3409 搬运礼物 CodeVS原创 时间限制: 1 s 空间限制: 64000 KB 题目等级 : 青铜 Bronze 题解 题目描述 Description 小浣熊松松特别喜欢交 ...
- [Xcode 实际操作]七、文件与数据-(18)使用MarkMan与设计师进行心灵沟通
目录:[Swift]Xcode实际操作 本文将演示MarkMan的使用. 在界面开发过程中,最终的效果和设计稿难免有些出入, 通常是颜色.位置.尺寸方面的偏差,使用MarkMan助你领会设计师的意图. ...