前言
最近这段时间,我一直寻找一个新的功能而不需云服务器来进行托管的,而在柳神的博客中翻看时有这么一篇文章。里面正好有一类没尝试过的东西,并且还是用json数据类型的,在查看仓库并且通过codex来为Nuxt适配,也就有这样一篇文章。
核心代码列表
/app/components/yjluo/hot/hotPageMain.vue:主体框架,将其他的vue模块进行链接减少整体难维护/app/components/yjluo/hot/hotPageHeader.vue:卡片顶部栏,作为展示热搜来源、热搜类型、热搜总数、热搜更新时间四类数据/app/components/yjluo/hot/hotPageLoading.vue:整体加载文件,在切换的时候加载/app/components/yjluo/hot/hotPagePagination.vue:底部导航条,作为无损切换不同页面展示且无需重新加载/app/components/yjluo/hot/hotCardList.vue:卡片列表,作为链接hotCardShow.vue的工具/app/components/yjluo/hot/hotCardShow.vue:展示出热搜
核心代码
主页面&主模块
<script setup lang="ts">
import HotPageCardItem from '~/components/yjluo/hot/hotPageMain.vue';
const hotTab = ['哔哩哔哩', '微博', '抖音', '知乎', '36氪', '百度']
const layoutStore = useLayoutStore()
// 设置侧边栏组件
layoutStore.setAside(['blog-stats', 'blog-tech', 'blog-log'])
</script>
<template>
<div class="HotPageMain">
<tab :tabs="hotTab">
<template v-slot:tab1>
<HotPageCardItem -cache='true' -name-type='哔哩哔哩' -mini-name-type='bilibili' -categrory-type='热搜' />
</template>
<template v-slot:tab2>
<HotPageCardItem -cache='true' -name-type='微博' -mini-name-type='weibo' -categrory-type='热搜' />
</template>
<template v-slot:tab3>
<HotPageCardItem -cache='true' -name-type='抖音' -mini-name-type='douyin' -categrory-type='热搜' />
</template>
<template v-slot:tab4>
<HotPageCardItem -cache='true' -name-type='知乎' -mini-name-type='zhihu' -categrory-type='热搜' />
</template>
<template v-slot:tab5>
<HotPageCardItem -cache='true' -name-type='36氪' -mini-name-type='36kr' -categrory-type='热搜' />
</template>
<template v-slot:tab6>
<HotPageCardItem -cache='true' -name-type='百度' -mini-name-type='baidu' -categrory-type='热搜' />
</template>
</tab>
</div>
</template>
<style lang="scss" scoped>
.HotPageMain {
padding: 1rem;
}
</style>
分模块
<script setup lang="ts">
const props = defineProps<{
miniNameType: 'bilibili' | 'weibo' | 'douyin' | 'zhihu' | '36kr' | 'baidu'
nameType: '哔哩哔哩' | '微博' | '抖音' | '知乎' | '36氪' | '百度'
categroryType: '热搜'
hotTotal: number
updateTime: string
}>()
const nowTimestamp = ref(Date.now())
let timer: ReturnType<typeof setInterval> | null = null
onMounted(() => {
timer = setInterval(() => {
nowTimestamp.value = Date.now()
}, 60 * 1000)
})
onBeforeUnmount(() => {
if (timer) {
clearInterval(timer)
timer = null
}
})
const relativeUpdateText = computed(() => {
if (!props.updateTime) return '暂无更新时间'
const updated = new Date(props.updateTime).getTime()
if (Number.isNaN(updated)) return '暂无更新时间'
const diff = nowTimestamp.value - updated
if (diff <= 0) return '刚刚更新'
const totalMinutes = Math.floor(diff / 1000 / 60)
const days = Math.floor(totalMinutes / (60 * 24))
const hours = Math.floor((totalMinutes % (60 * 24)) / 60)
const minutes = totalMinutes % 60
if (days > 0) return `${days}天前更新`
if (hours === 0 && minutes === 0) return '刚刚更新'
if (hours <= 0 && minutes > 0) return `${minutes}分钟前更新`
if (hours > 0 && minutes === 0) return `${hours}小时前更新}`
return `${hours}小时${minutes}分钟前更新`
})
</script>
<template>
<div class="cardMainHeader">
<div class="mainHeaderIcon">
<NuxtImg
:src="`/image/PageImageAssets/hot/${miniNameType}.avif`"
:alt="nameType"
width="32"
height="32"
/>
</div>
<div class="mainHeaderName">
<span>{{ nameType }}</span>
<small class="category">{{ categroryType }}</small>
</div>
<div class="mainHeaderData">
<div class="headerData">
共 {{ hotTotal }} 条 · {{ relativeUpdateText }}
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
$text-tertiary: #999;
$border-lighter: #f5f5f5;
$spacing-md: 12px;
$spacing-lg: 16px;
.cardMainHeader {
display: flex;
align-items: center;
gap: $spacing-md;
margin-bottom: $spacing-lg;
padding-bottom: $spacing-md;
border-bottom: 1px solid $border-lighter;
.mainHeaderName {
flex: 1;
display: flex;
flex-direction: column;
.category {
color: $text-tertiary;
font-size: 12px;
}
}
.mainHeaderData {
display: flex;
align-items: flex-end;
font-size: 12px;
.headerData {
font-weight: bold;
position: relative;
}
}
}
</style>

评论区
评论加载中...