#
VitePress真是太好用了
2026-02-23
下载卡片组件开发
详细介绍如何开发一个高性能的下载卡片组件DownloadCard,用于在VitePress中展示资源下载链接。涵盖组件需求分析、Vue3+TypeScript代码实现、组件注册方法、随机马卡龙色背景、按钮文字动态切换、响应式布局与暗色模式适配等核心功能的完整开发流程。
下载卡片组件开发
组件需求
在资源下载页面中,我们需要一个能够集中展示多个下载链接的卡片组件,满足以下需求:
- 支持多个下载链接,每个链接单独显示为一个卡片
- 每个卡片显示:名称、描述、下载按钮
- 根据链接类型动态切换按钮文字(下载/前往)
- 卡片使用随机马卡龙色背景,每次刷新或添加新卡片时颜色不同
- 响应式设计,适配移动端和桌面端
- 悬浮动效提升用户体验
组件实现
创建文件 docs/.vitepress/theme/components/DownloadCard.vue:
<script setup lang="ts">
import { computed } from 'vue'
interface DownloadItem {
name: string
url: string
description?: string
}
interface Props {
downloads: DownloadItem[]
}
const props = defineProps<Props>()
const macaronColors = [
'rgba(255, 182, 193, 0.25)',
'rgba(173, 216, 230, 0.25)',
'rgba(144, 238, 144, 0.25)',
'rgba(255, 218, 185, 0.25)',
'rgba(221, 160, 221, 0.25)',
'rgba(175, 238, 238, 0.25)',
'rgba(255, 255, 224, 0.25)',
'rgba(230, 230, 250, 0.25)',
]
const getRandomColor = (index: number) => {
return macaronColors[index % macaronColors.length]
}
const getBtnText = (url: string) => {
if (url.includes('qm.qq.com') || url.includes('qq.com')) {
return '立即前往'
}
return '立即下载'
}
</script>
<template>
<div v-if="downloads && downloads.length > 0" class="download-section">
<div
v-for="(item, index) in downloads"
:key="index"
class="download-card"
:style="{ backgroundColor: getRandomColor(index) }"
>
<div class="download-icon">
<svg viewBox="0 0 24 24" width="24" height="24">
<path fill="currentColor" d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
</svg>
</div>
<div class="download-content">
<div class="download-header">
<span class="download-name">{{ item.name }}</span>
</div>
<p v-if="item.description" class="download-desc">{{ item.description }}</p>
<a :href="item.url" class="download-btn" target="_blank">
<span>{{ getBtnText(item.url) }}</span>
<svg viewBox="0 0 24 24" width="16" height="16">
<path fill="currentColor" d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/>
</svg>
</a>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.download-section {
display: flex;
flex-direction: column;
gap: 16px;
margin: 1.5rem 0;
}
.download-card {
display: flex;
gap: 16px;
padding: 16px 20px;
border-radius: 12px;
border: none;
backdrop-filter: blur(10px);
transition: all 0.3s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}
}
.download-icon {
flex-shrink: 0;
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.4);
border-radius: 12px;
color: var(--vp-c-text-1);
}
.download-content {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 8px;
}
.download-header {
display: flex;
align-items: center;
justify-content: space-between;
}
.download-name {
font-size: 1.1rem;
font-weight: 600;
color: var(--vp-c-text-1);
&::before {
display: none !important;
}
}
.download-desc {
font-size: 0.9rem;
color: var(--vp-c-text-2);
line-height: 1.5;
margin: 0;
}
.download-btn {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 8px 16px;
background: rgba(0, 0, 0, 0.15);
color: var(--vp-c-text-1);
border-radius: 8px;
text-decoration: none;
font-size: 0.9rem;
font-weight: 500;
transition: all 0.3s ease;
width: fit-content;
border: none;
&:hover {
background: rgba(0, 0, 0, 0.25);
transform: translateY(-1px);
}
svg {
flex-shrink: 0;
}
&::before {
display: none !important;
}
}
@media (max-width: 640px) {
.download-card {
padding: 12px 16px;
gap: 12px;
}
.download-icon {
width: 40px;
height: 40px;
}
.download-name {
font-size: 1rem;
}
}
</style>组件注册
在 docs/.vitepress/theme/index.ts 中注册组件:
import DownloadCard from "./components/DownloadCard.vue";
export default {
enhanceApp({ app }) {
app.component('DownloadCard', DownloadCard);
},
}组件使用
在 Markdown 文件中使用:
<DownloadCard :downloads="[
{ name: 'Github', url: 'https://github.com/xxx/release.zip', description: '官方下载地址,可能需要代理' },
{ name: 'Github 加速', url: 'https://gh-proxy.org/https://github.com/xxx/release.zip', description: '使用 Gh Proxy 加速下载' },
{ name: '百度网盘', url: 'https://pan.baidu.com/s/xxx?pwd=xxxx', description: '使用百度网盘进行下载,提取码:xxxx' },
{ name: 'QQ群', url: 'https://qm.qq.com/q/xxx', description: '加入 QQ 群下载资源' }
]" />关键实现点
1. 随机马卡龙色背景
通过数组存储多种马卡龙色,使用索引取模实现每个卡片不同的颜色:
const macaronColors = [
'rgba(255, 182, 193, 0.25)', // 粉色
'rgba(173, 216, 230, 0.25)', // 浅蓝色
'rgba(144, 238, 144, 0.25)', // 浅绿色
// ... 更多颜色
]
const getRandomColor = (index: number) => {
return macaronColors[index % macaronColors.length]
}2. 按钮文字动态切换
根据链接类型动态显示不同的按钮文字,QQ链接显示"立即前往",其他链接显示"立即下载":
const getBtnText = (url: string) => {
if (url.includes('qm.qq.com') || url.includes('qq.com')) {
return '立即前往'
}
return '立即下载'
}3. 屏蔽链接图标
通过 CSS 伪元素 ::before 屏蔽主题自带的链接图标:
.download-name, .download-btn {
&::before {
display: none !important;
}
}4. 响应式设计
使用媒体查询适配移动端:
@media (max-width: 640px) {
.download-card {
padding: 12px 16px;
gap: 12px;
}
.download-icon {
width: 40px;
height: 40px;
}
}参数说明
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| downloads | DownloadItem[] | 是 | 下载项数组 |
DownloadItem 类型
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| name | string | 是 | 下载项名称 |
| url | string | 是 | 下载链接 |
| description | string | 否 | 下载项描述 |
本文由 DoubleSpirit121 原创
采用 CC BY-NC-SA 4.0 协议进行许可
TAGS:
VitePress 1.6.3
0 评论