33 <v-divider class =" mb-2" />
44 <div class =" d-flex justify-space-between align-center mb-2" >
55 <div class =" text-subtitle-2" >{{ totalCount }} 条回复</div >
6- <div class =" d-flex" v-if =" showAll" >
7- <v-btn
8- x-small
9- outlined
10- class =" mr-1"
11- :color =" sortBy === 'latest' ? 'primary' : ''"
12- @click =" changeSort('latest')"
13- >
14- 最新
15- </v-btn >
16- <v-btn
17- x-small
18- outlined
19- :color =" sortBy === 'hottest' ? 'primary' : ''"
20- @click =" changeSort('hottest')"
21- >
22- 最热
23- </v-btn >
24- </div >
256 </div >
267
278 <div v-if =" loading" class =" py-2 d-flex justify-center" >
289 <v-progress-circular indeterminate color =" primary" size =" 20" />
2910 </div >
3011
3112 <div v-else >
13+ <!-- 排序和折叠控件 (仅在showAll时显示) -->
14+ <div v-if =" showAll" class =" d-flex justify-space-between align-center mb-2" >
15+ <div class =" d-flex gap" >
16+ <v-btn
17+ x-small
18+ outlined
19+ class =" mr-1"
20+ :color =" sortBy === 'latest' ? 'primary' : ''"
21+ @click =" changeSortType('latest')"
22+ >
23+ 最新
24+ <v-icon right x-small v-show =" sortBy === 'latest'" >{{ sortDirection === 'desc' ? icons.mdiChevronDown : icons.mdiChevronUp }}</v-icon >
25+ </v-btn >
26+ <v-btn
27+ x-small
28+ outlined
29+ :color =" sortBy === 'hottest' ? 'primary' : ''"
30+ @click =" changeSortType('hottest')"
31+ >
32+ 最热
33+ <v-icon right x-small v-show =" sortBy === 'hottest'" >{{ sortDirection === 'desc' ? icons.mdiChevronDown : icons.mdiChevronUp }}</v-icon >
34+ </v-btn >
35+ </div >
36+ <v-btn
37+ x-small
38+ text
39+ color =" primary"
40+ @click =" collapseReplies"
41+ >
42+ 折叠
43+ </v-btn >
44+ </div >
45+
46+ <!-- 分页信息 (仅在showAll时显示) -->
47+ <div v-if =" showAll" class =" text-caption grey--text mb-2" >
48+ 第 {{ currentPage }} 页,共 {{ totalPages }} 页
49+ </div >
3250 <v-card
33- v-for =" reply in replies "
51+ v-for =" reply in paginatedReplies "
3452 :key =" reply.id"
3553 outlined
3654 class =" mb-2 pa-2 reply-card"
90108 </div >
91109 </v-card >
92110
111+ <!-- 分页导航 (仅在showAll时显示) -->
112+ <div v-if =" showAll" class =" d-flex justify-center align-center mt-4 gap-2" >
113+ <v-btn
114+ x-small
115+ outlined
116+ :disabled =" currentPage === 1"
117+ @click =" currentPage--"
118+ >
119+ 上一页
120+ </v-btn >
121+ <span class =" text-caption mx-2" >{{ currentPage }} / {{ totalPages }}</span >
122+ <v-btn
123+ x-small
124+ outlined
125+ :disabled =" currentPage === totalPages"
126+ @click =" currentPage++"
127+ >
128+ 下一页
129+ </v-btn >
130+ </div >
131+
93132 <v-btn
94133 v-if =" !showAll && totalCount > filteredCount"
95134 text
@@ -157,6 +196,8 @@ import {
157196 mdiThumbDown ,
158197 mdiShareVariantOutline ,
159198 mdiReplyOutline ,
199+ mdiChevronUp ,
200+ mdiChevronDown ,
160201} from ' @mdi/js' ;
161202import AvatarContainer from ' @/components/users/profile/AvatarContainer' ;
162203import ReplyChainDialog from ' @/components/courses/ReplyChainDialog' ;
@@ -193,7 +234,10 @@ export default {
193234 totalCount: 0 ,
194235 filteredCount: 0 ,
195236 sortBy: ' latest' ,
237+ sortDirection: ' desc' ,
196238 showAll: false ,
239+ currentPage: 1 ,
240+ pageSize: 10 ,
197241 replyContent: ' ' ,
198242 replyTarget: null ,
199243 isAnonymous: false ,
@@ -204,16 +248,42 @@ export default {
204248 mdiThumbDown,
205249 mdiShareVariantOutline,
206250 mdiReplyOutline,
251+ mdiChevronUp,
252+ mdiChevronDown,
207253 },
208254 };
209255 },
256+ computed: {
257+ totalPages () {
258+ return Math .ceil (this .replies .length / this .pageSize );
259+ },
260+ paginatedReplies () {
261+ if (! this .showAll ) {
262+ return this .replies .slice (0 , this .filteredCount );
263+ }
264+ const start = (this .currentPage - 1 ) * this .pageSize ;
265+ const end = start + this .pageSize ;
266+ return this .replies .slice (start, end);
267+ },
268+ },
210269 watch: {
211270 commentId: {
212271 immediate: true ,
213272 handler () {
214273 this .fetchReplies ();
215274 },
216275 },
276+ sortDirection () {
277+ if (this .showAll ) {
278+ this .currentPage = 1 ;
279+ this .replies .reverse ();
280+ }
281+ },
282+ showAll: {
283+ handler () {
284+ this .currentPage = 1 ;
285+ },
286+ },
217287 },
218288 methods: {
219289 unixToReadable,
@@ -279,11 +349,29 @@ export default {
279349 this .sortBy = sortBy;
280350 this .fetchReplies ();
281351 },
352+ changeSortType (sortBy ) {
353+ if (this .sortBy === sortBy) {
354+ this .sortDirection = this .sortDirection === ' desc' ? ' asc' : ' desc' ;
355+ return ;
356+ }
357+ this .sortBy = sortBy;
358+ this .sortDirection = ' desc' ;
359+ this .currentPage = 1 ;
360+ this .fetchReplies ();
361+ },
362+ collapseReplies () {
363+ this .showAll = false ;
364+ this .totalCount = this .replies .length ;
365+ this .replies = this .replies .filter (reply => reply .like >= 5 );
366+ this .filteredCount = this .replies .length ;
367+ this .currentPage = 1 ;
368+ },
282369 showAllReplies () {
283370 if (this .showAll ) {
284371 return ;
285372 }
286373 this .showAll = true ;
374+ this .currentPage = 1 ;
287375 this .fetchReplies ();
288376 },
289377 setReplyTarget (reply ) {
@@ -392,4 +480,7 @@ export default {
392480 border-left : 3px solid rgba (0 , 0 , 0 , 0.1 );
393481 }
394482}
483+ .gap {
484+ gap : 8px ;
485+ }
395486 </style >
0 commit comments