vue项目day05
4、完成收藏文章功能
- 功能一:实现收藏按钮的效果
- 已收藏:显示红色
- 未收藏:显示黑马
- 这里我们使用动态行内样式来完成这个功能,然后我们还需要知道如何来判断当前文章是否已收藏,那如何判断呢?答:后端文章详情接口中返回了一个has_star属性,当这个属性值为true表示已收藏,false表示未收藏。 +
- 功能二:实现收藏功能
- 用户角度分析:点击收藏按钮,实现收藏效果
- 程序员角度分析:给收藏按钮绑定点击事件 声明事件处理函数,然后再事件处理函数中调用收藏接口实现收藏功能
- 拆解步骤:
- 1、给收藏按钮绑定点击事件 声明事件处理函数
- 2、封装“收藏”接口函数
- 3、引入接口函数,并在事件处理函数中调用接口实现收藏功能
8、评论列表
1、创建commentList.vue组件
2、配置路由
3、布局
4、实现功能
1、渲染评论列表
用户角度分析:用户点击文章详情页面中的 “评论数量”或者“更多跟帖”按钮,跳转到评论列表页面,进入页面就可以立刻看到评论的数据。
程序员角度分析:在文章详情页面,给“更多跟帖”和“评论数量”绑定点击事件,并通过事件处理函数跳转到评论列表页面,然后在created中调用接口,请请并保存数据,渲染数据。
拆解步骤:
- 1、在文章详情页面,给“更多跟帖”和“评论数量”绑定点击事件,并通过事件处理函数跳转到评论列表页面
- 2、封装 “获取评论列表”的接口函数
- 3、评论列表页面引入接口函数,并在created中调用 接口,请求并保存数据
- 4、根据数据渲染
2、渲染评论中的嵌套评论内容
问题1:嵌套评论的内容是如何产生的?答:是通过回复评论产生的,那么数据中如何体现出来呢?答:通过parent属性,当parent为null的时候表示改评论为直接评论,当parent为对象的时候,表示存在嵌套评论。
- 1、把嵌套评论的结构实现出来
- 2、根据parent判断,然后进行渲染
3、递归组件的使用
问题:评论内容有多层嵌套,且第二层以及第三层之后的所有嵌套都是一样的结构和样式,因此我们可以把嵌套评论内容部分封装起来,然后使用递归组件渲染内容。
封装src/commentItem.vue递归组件
<template>
<div class="commentItem">
<div class="top">
<div class="left">
<span>{{item.user.nickname}}</span>
<span>2分钟前</span>
</div>
<span>回复</span>
</div>
<!-- 第二层嵌套 start
递归组件:自己调用了自己,但是一定要有结束的判断
-->
<commentItem v-if="item.parent" :item="item.parent"></commentItem>
<!-- 第二层嵌套 end -->
<div class="bottom">{{item.content}}</div>
</div>
</template>
<script>
export default {
// props: ["item"]
// name属性相当于通过components注册了该组件,name的值就是注册的组件名
name: "commentItem",
props: {
item: {
type: Object, // 规定传入的item的数据类型
required: true // 规定使用组件时,item为必传
}
}
}
</script>
<style lang="less" scoped>
.commentItem {
border: 1px solid #ccc;
padding: 5px;
margin-top: 10px;
.top {
font-size: 12px;
color: #aaa;
display: flex;
justify-content: space-between;
}
.bottom {
font-size: 13px;
line-height: 40px;
}
}
</style>
2、发表评论
- 1、点击底部输入框,显示文本域。
发表评论有以下几种情况:
1、直接对文章发表评论
2、点击最外层的回复按钮,进行评论
3、点击第一层嵌套的回复按钮,进行评论
4、点击递归组件生成的嵌套的回复按钮,进行评论
-
1、直接对文章发表评论
- 用户角度分析:点击底部输入,显示文本域,输入评论内容,点击发送按钮,进行评论。
- 程序员角度分析:给底部输入框绑定事件,控制文本域的显示,收集用户输入的评论内容,给“发送”绑定点击事件,在事件处理函数中调用接口进行发表评论。
- 拆解步骤:
- 1、给底部输入框绑定事件,控制文本域的显示,
- 2、声明变量,v-model双向绑定文本域
- 3、给“发送”按钮绑定点击事件,并声明事件处理函数
- 4、封装“发表评论”的接口函数
- 5、在事件处理函数中调用“发表评论”接口,实现发表功能。
-
2、点击最外层的回复按钮,进行评论
- 用户角度分析:用户点击回复按钮,显示底部文本域,输入评论内容,点击发送按钮,发表成功了。
- 程序员角度分析:给回复按钮绑定点击事件,并声明事件处理函数,控制底部文本域的显示,收集用户输入的评论内容,给发送按钮绑定点击事件,调用接口实现发表评论。
- 拆解步骤:
- 1、给回复按钮绑定点击事件,并声明事件处理函数
- 2、事件处理函中控制底部文本域的显示
- 3、收集用户输入的评论内容 ---- 上一个功能已经实现了
- 4、给发送按钮绑定点击事件,并声明事件处理函数。 --- 上一个功能已经实现了
- 5、封装接口函数,调用接口函数。 ---- 上一个功能已经实现了
- 注意:此刻我们是回复评论,因此接口需要添加多一个参数,这个参数就是parent_id。
-
3、点击第一层嵌套的回复按钮,进行评论
- 用户角度分析:用户点击回复按钮,显示底部文本域,输入评论内容,点击发送按钮,发表成功了。
- 程序员角度分析:给回复按钮绑定点击事件,在事件处理函数中控制底部组件文本域的显示,收集用户输入的评论内容,给发送按钮绑定点击事件,调用接口实现发表评论。
- 拆解步骤:
- 1、给回复按钮绑定点击事件,并声明事件处理函数
- 2、在函数中控制底部组件文本域的显示,以及把回复评论的id传递给子组件
- 因为控制底部组件文本域的显示已经在父组件中实现了,因此我们可以在commentItem组件中通过子传父,通知父组件控制底部组件文本域的显示即可,
- 因为id传递给底部组件也已经在父组件中实现了,因为,我们可以在commentItem组件中通过子传父,把id传递给父组件,父组件再传递底部组件。
-
4、点击递归组件生成的嵌套的回复按钮,进行评论
-
用户角度分析:用户点击回复按钮,显示底部文本域,输入评论内容,点击发送按钮,发表成功了。
-
程序员角度分析:给回复按钮绑定点击事件,在事件处理函数中控制底部组件文本域的显示,收集用户输入的评论内容,给发送按钮绑定点击事件,调用接口实现发表评论。
-
因为递归组件生成的回复按钮,已经在上一个功能中绑定了自定义事件,并且进行了父传子,因此我们只需在父组件commentItem组件中绑定自定义事件,并在事件处理函数中进行子传父即可
-
在commentItem组件中添加如下代码即可
<template> <div class="commentItem"> ..... <!-- 第二层嵌套 start 递归组件:自己调用了自己,但是一定要有结束的判断 添加 @replyEvent="replyFn"事件完成,递归组件生成的回复按钮功能 --> <commentItem v-if="item.parent" :item="item.parent" @replyEvent="replyFn"></commentItem> .... </template>
-