点击发布评论,会有弹出层,用vant写出弹出层,弹出层对发布评论的页面来说,是爷爷,要经过两次传参.
item中
@click="$emit('recleClick', comment)"
list中
@recleClick="$emit('recleClick', $event)"
index,中
@recleClick="recleClick"
来判断弹出层是否要打开
设置样式.发布评论要验证是否登录,没有登录,点击发布评论,会跳到登录页,登录,
if (!this.$store.state.user) {
return this.$toast("请先登录");
}
用户登录之后,点击发布评论,需要发送请求,封装请求,调用请求,获取数据.
发布内容为空的话,发布按钮禁止点击
:disabled="!message.length"
回复评论,
父子通信的props如果是一个 数组,我们只要不重新赋值这个props里面的数组,就都不算修改props,而可以实现父子之间共享数据,实时变化。(其本质是父子用了一个引用数据类型的数据)
实现:子组件comment-list将 data里面的变量list修改成 props里面的属性list 用于去接收外面的空数组commentList
data () {
return {
// 其他变量...
// list: [], // <===注释掉
}
}
props: {
// 其他属性...
// 定义自定义属性list,去接收外面的commentList 变量
list: {
type: Array,
default: () => [] //复杂数据类型,要用函数的方式
}
}
父组件:
data(){
return{
// 其他变量...
commentList: [] // 评论列表
}
}
<!-- 文章评论列表 -->
<comment-list
:source="article.art_id"
:list="commentList"
@onload-success="totalCommentCount = $event.total_count"
/>
methods: {
onSuccessPost(comment) {
console.log(comment);
this.isReplyShow = false;
//将发布的内容展示在页面顶部
this.commentList.unshift(comment.new_obj); // <=== 精华之句!!!
},
},
父组件的空数组不是为了传递给子组件,是让子组件把数据列表共享给父组件,因为父子通信关联的是引用数据类型,任何人一方改变了,另外一方都会变化。
核心:组件之间如果共享的是一个引用数据类型,任何一个组件修改(不赋值),其他都会变化。
列表数据重复的问题:
原因: van-list 组件有个特点,就是只有在可视范围内才会自动调用load事件,所以我们之前文章内容过长,就不会触发请求文章评论列表,故而 我们手动在created里面调用了onLoad方法,但是现在我们这里的回复列表一开始就在可是范围内,故而会触发2次请求,1次是可视范围内自动触发,1次是我们主动调用触发。所以我们要关闭 自动检测可视范围自动调用。
实现:
给van-list组件设置immediate-check 属性,关闭可视范围自动调用检测
<!--
只有 List 在可视范围内才会检查滚动位置触发 onLoad
-->
<van-list
v-model="loading"
:finished="finished"
finished-text="已显示全部评论"
:error="error"
error-text="加载失败,请点击重试"
:immediate-check="false"
@load="onLoad"
>
created () {
// 当手动初始 onLoad 的话,它不会自动开始初始的 loading
// 所以我们要手动的开启初始 loading
this.loading = true
this.onLoad()
}
回复列表内容不更新的问题:
弹层组件(van-popup):
如果初始的条件是 false,则弹层的内容不会渲染
程序运行期间,当条件变为 true 的时候,弹层才渲染了内容
之后切换弹层的展示,弹层只是通过 CSS 控制隐藏和显示
原因: 弹层渲染出来以后就只是简单的切换显示和隐藏,里面的内容也不再重新渲染了,所以会导致我们的评论的回复列表不会动态更新了。解决办法就是在每次弹层显示的时候重新渲染组件。
<!-- 评论回复 -->
<!--
弹出层是懒渲染的:只有在第一次展示的时候才会渲染里面的内容,之后它的关闭和显示都是在切换内容的显示和隐藏
-->
<van-popup v-model="isReplyShow"position="bottom" style="height: 100%;">
<!--
v-if 条件渲染
true:渲染元素节点
false:不渲染
-->
<comment-reply
v-if="isReplyShow"
:comment="currentComment"
@close="isReplyShow = false"
/>
</van-popup>
<!-- /评论回复 -->
vue依赖注入:官网
可以在组件之间传递数据:
provide: function () {
return {
articleId: this.articleId,
};
},
inject: {
articleId:{
type: [String, Number],
default: null,
}