在图片详情的评论区域和商品的评论区域大致结构是一样的,只有一些数据是不一样的。因此我们可以创建一个组件作为子组件,通过子组件和父组件之间传值的方式实现组件的复用
父组件向子组件传值
父组件向子组件通过 props
,父组件中通过属性绑定的方式传递,在子组件中创建props
数组接收父组件传过来的数据
子组件向父组件传值
子组件向父组件传值通过 $emit
的方式,在子组件中绑定一个触发事件,在事件中 this.$emit('事件',传值)
,在父组件中通过 @事件=“事件处理程序”
执行
子组件
<template>
<div>
<!-- 发表评论区域 -->
<h4>发表评论</h4>
<hr />
<van-form>
<van-field
@change="$emit('change', $event.target.value)"
rows="3"
autosize
type="textarea"
placeholder="请输入留言"
/>
<van-button block type="info" native-type="submit" @click="clickCommentHandle">发表评论</van-button>
</van-form>
<!-- 评论列表区域 -->
<div class="comments">
<div class="comment-item" v-for="(item, index) in commentList" :key="index">
<div class="tit">
<span>第{{index + 1}}楼</span>
<span>用户: {{item.user_name}}</span>
<span>发表时间:{{item.add_time | dateFormat}}</span>
</div>
<div class="content">{{item.content}}</div>
</div>
<!-- 加载更多按钮 -->
<van-button
block
plain
size="normal"
type="danger"
v-if="newComment !== []"
@click="getMoreComment"
>加载更多</van-button>
<!-- 我是有底线的 -->
<div class="footer" v-show="footerVisable" v-else>-----我是有底线的-----</div>
</div>
</div>
</template>
<script>
export default {
props: ['commentList', 'newComment'],
methods: {
// 点击加载更多评论按钮
getMoreComment() {
this.$emit('commentsItem')
},
// 点击发表评论按钮
clickCommentHandle() {
this.$emit('addComment')
}
}
}
</script>
<style lang="less" scoped>
.van-field[data-v-4e7c9004] {
border: 1px solid #ccc;
margin-bottom: 5px;
}
.van-button {
margin-top: 5px;
}
.comments {
margin-top: 5px;
font-size: 12px;
line-height: 30px;
.comment-item {
.tit {
height: 30px;
background-color: #cccccc;
span {
margin-right: 5px;
}
}
.content {
font-size: 12px;
}
}
.footer {
height: 30px;
text-align: center;
font-size: 12px;
line-height: 30px;
}
}
</style>
父组件
<template>
<div class="goodsComment">
<comments-item
:commentList="commentList"
:newComment="newComment"
@commentsItem="getMoreComment"
@addComment="addComment"
@change="changeInputValue"
></comments-item>
</div>
</template>
<script>
import Comments from '../../components/comments.vue'
export default {
data() {
return {
commentsValue: '',
commentList: [],
artid: '',
pageindex: 1,
footerVisable: false,
newComment: []
}
},
components: {
'comments-item': Comments
},
created() {
this.artid = this.$route.params.id
this.getCommentList()
},
methods: {
// 获取评论内容
// 获取分类图片评论列表
async getCommentList() {
const res = await this.$axios.get(
`/api/getcomments/${this.artid}?pageindex=1`
)
if (res.status !== 0) {
return this.Toast.fail('获取评论列表失败')
}
this.commentList = res.message
},
// 点击加载更多按钮
async getMoreComment() {
this.pageindex += 1
const res = await this.$axios.get(
`/api/getcomments/${this.artid}?pageindex=${this.pageindex}`
)
if (res.status !== 0) {
return this.Toast.fail('加载失败')
}
this.newComment = res.message
if (this.newComment !== []) {
return this.commentList.push(...res.message)
} else {
return this.commentList
}
},
// 添加评论
async addComment() {
if (this.commentsValue.trim() === '') {
return this.$toast.fail('请输入评论内容')
}
const res = await this.$axios.post(`/api/postcomment/${this.artid}`, {
content: this.commentsValue
})
this.Toast.success(res.message)
this.commentsValue = ''
this.getCommentList()
},
changeInputValue(data) {
this.commentsValue = data
}
}
}
</script>
<style lang="less" scoped>
.goodsComment {
margin-bottom: 50px;
}
</style>