一、代码展示
< template> < div class = " article-ranking" > < div class = " header" > < h2 class = " title" > {{ title }}</ h2> </ div> < div class = " ranking-list" > < div v-for = " (article, index) in articles" :key = " index" class = " article-item" > < div class = " article-info" > < h3 class = " article-title" > {{ truncateTitle(article.title, 25) }}</ h3> < p class = " article-content" > {{ truncateContent(article.summary, 50) }}</ p> < div class = " details" > < div class = " info-row" > < p class = " info-text" > 时间: < span class = " time" > {{ formatPublishTime(article.createTime) }}</ span> | 浏览量: < span class = " count" > {{ formatViews(article.likeCount).formattedValue }}</ span>
</ p> </ div> </ div> </ div> < div class = " divider" > </ div> </ div> </ div> < div class = " footer" > < a @click = " viewFullRanking" href = " #" class = " full-ranking-link" > 查看完整榜单</ a> </ div> </ div>
</ template> < script setup >
import { defineProps } from 'vue' ; const props = defineProps ( [ 'title' , 'articles' ] ) ; const viewFullRanking = ( ) => { console. log ( 'View Full Ranking' ) ;
} ; const truncateContent = ( content, maxLength ) => { return content. length > maxLength ? content. substring ( 0 , maxLength) + '...' : content;
} ; const truncateTitle = ( title, maxLength ) => { return title. length > maxLength ? title. substring ( 0 , maxLength) + '...' : title;
} ; const formatPublishTime = ( publishTime ) => { const currentDate = new Date ( ) ; const articleDate = new Date ( publishTime) ; const timeDiff = currentDate - articleDate; const oneDay = 24 * 60 * 60 * 1000 ; const oneMonth = oneDay * 30 ; if ( timeDiff < oneDay) { const hours = Math. floor ( timeDiff / ( 60 * 60 * 1000 ) ) ; return ` ${ hours} 小时前 ` ; } else if ( timeDiff < oneMonth) { const days = Math. floor ( timeDiff / oneDay) ; return ` ${ days} 天前 ` ; } else { const months = Math. floor ( timeDiff / oneMonth) ; return ` ${ months} 个月前 ` ; }
} ; const formatAbbreviation = ( value ) => { if ( value >= 10000 ) { return { formattedValue : Math. floor ( value / 1000 ) + 'w+' , isLargeCount : true , } ; } else { return { formattedValue : value, isLargeCount : false , } ; }
} ; const formatViews = ( views ) => formatAbbreviation ( views) ; const formatLikes = ( likes ) => formatAbbreviation ( likes) ;
</ script> < style scoped >
.article-ranking { width : 300px; border : 1px solid #ccc; border-radius : 8px; padding : 16px; margin : 16px; font-family : 'Arial' , sans-serif;
} .article-title { font-size : 18px; margin-bottom : 8px; color : #333; text-align : left;
} .article-content { font-size : 14px; color : #777; margin-bottom : 8px; overflow : hidden; text-overflow : ellipsis; white-space : nowrap; text-align : left;
} .ranking-list { display : flex; flex-direction : column;
} .article-item { padding : 8px;
} .article-info { display : flex; flex-direction : column;
} .details { flex-grow : 1;
} .info-row { display : flex; flex-wrap : wrap; justify-content : space-between;
} .time { font-weight : bold; color : #1890ff;
} .count { font-weight : bold; color : #1890ff;
} .large-count { font-size : 12px;
} .divider { height : 1px; background-color : #ddd; margin : 8px 0;
} .footer { text-align : center; margin-top : 16px;
} .full-ranking-link { font-size : 14px; color : #1890ff; text-decoration : none;
} .full-ranking-link:hover { text-decoration : underline;
}
</ style>
二、代码解读
<template>
部分:
整个模板包含一个名为 “article-ranking” 的 div
,宽度为300像素,具有圆角边框和一些内外边距,呈现为一个简单的排行榜容器。 模板包含标题(“header”)、排行列表(“ranking-list”)、文章项(“article-item”)、文章信息(“article-info”)、详细信息(“details”)、分隔线(“divider”)和页脚(“footer”)。 <script setup>
部分:
使用 import { defineProps } from 'vue';
导入 defineProps
方法,以定义组件的属性。 使用 defineProps(['title', 'articles']);
定义了两个属性:title
和 articles
。 定义了一个 viewFullRanking
方法,用于在点击 “查看完整榜单” 链接时输出一条日志。 定义了 truncateContent
和 truncateTitle
方法,用于截断文章内容和标题,以确保它们不会超过指定的长度。 定义了 formatPublishTime
方法,用于根据发布时间计算并返回相对于当前时间的时间差,以便显示多久前发布的文章。 定义了 formatAbbreviation
方法,用于根据数值的大小返回格式化后的数值,并标记是否为较大的计数。 定义了 formatViews
和 formatLikes
方法,这两个方法分别使用 formatAbbreviation
处理浏览量和点赞数。 <style scoped>
部分:
对排行榜容器及其子元素进行样式定义。 调整了标题和文章内容的样式,使其居左对齐。 使用了 flex 布局来组织文章项和详细信息。 设置了一些通用的样式,如字体大小、颜色、边框等。 使用了一些特定样式,如 divider
类,用于添加分隔线效果。 样式中还包含了一些交互效果,如链接的鼠标悬停样式。
三、结果展示