一、代码展示
< 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
类,用于添加分隔线效果。 样式中还包含了一些交互效果,如链接的鼠标悬停样式。
三、结果展示