vue实现多条回复展开
实现多条回复展开功能
在Vue中实现多条回复展开功能,可以通过v-for指令遍历回复列表,结合v-show或v-if控制每条回复的显示状态。以下是一个完整的实现方案:
基础实现代码
<template>
<div>
<div v-for="(reply, index) in replies" :key="reply.id">
<div class="reply-content">
{{ reply.content }}
</div>
<button @click="toggleReply(index)">
{{ isExpanded[index] ? '收起' : '展开' }}回复
</button>
<div v-show="isExpanded[index]" class="sub-replies">
<div v-for="subReply in reply.subReplies" :key="subReply.id">
{{ subReply.content }}
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
replies: [
{
id: 1,
content: '主回复1',
subReplies: [
{ id: 11, content: '子回复1-1' },
{ id: 12, content: '子回复1-2' }
]
},
{
id: 2,
content: '主回复2',
subReplies: [
{ id: 21, content: '子回复2-1' },
{ id: 22, content: '子回复2-2' }
]
}
],
isExpanded: []
}
},
created() {
this.isExpanded = this.replies.map(() => false)
},
methods: {
toggleReply(index) {
this.$set(this.isExpanded, index, !this.isExpanded[index])
}
}
}
</script>
优化后的组件实现
对于更复杂的场景,可以将回复项提取为单独组件:

<template>
<div>
<ReplyItem
v-for="reply in replies"
:key="reply.id"
:reply="reply"
/>
</div>
</template>
<script>
import ReplyItem from './ReplyItem.vue'
export default {
components: { ReplyItem },
data() {
return {
replies: [
// 同上
]
}
}
}
</script>
ReplyItem.vue组件:

<template>
<div class="reply-item">
<div class="main-reply">{{ reply.content }}</div>
<button @click="isExpanded = !isExpanded">
{{ isExpanded ? '收起' : '展开' }}回复({{ reply.subReplies.length }})
</button>
<div v-show="isExpanded" class="sub-replies">
<div v-for="subReply in reply.subReplies" :key="subReply.id">
{{ subReply.content }}
</div>
</div>
</div>
</template>
<script>
export default {
props: ['reply'],
data() {
return {
isExpanded: false
}
}
}
</script>
动画效果增强
可以为展开/收起添加过渡动画:
<template>
<transition name="slide">
<div v-show="isExpanded" class="sub-replies">
<!-- 子回复内容 -->
</div>
</transition>
</template>
<style>
.slide-enter-active, .slide-leave-active {
transition: all 0.3s ease;
max-height: 500px;
overflow: hidden;
}
.slide-enter, .slide-leave-to {
max-height: 0;
opacity: 0;
}
</style>
性能优化建议
对于大量回复的情况,可以采用虚拟滚动技术:
<template>
<RecycleScroller
class="scroller"
:items="replies"
:item-size="50"
key-field="id"
>
<template v-slot="{ item }">
<ReplyItem :reply="item" />
</template>
</RecycleScroller>
</template>
<script>
import { RecycleScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
export default {
components: { RecycleScroller, ReplyItem }
}
</script>
以上实现方案可根据实际需求进行调整,如添加分页加载、回复表单等功能。






