#
VitePress真是太好用了
2026-02-23
作者卡片组件开发
详细介绍如何开发一个高性能的作者卡片组件AuthorCard,用于在VitePress中展示作者信息。涵盖组件需求分析、Vue3+TypeScript代码实现、组件注册方法、随机马卡龙色背景、插槽传值、响应式布局与暗色模式适配等核心功能的完整开发流程,还包含将长文本内容作为插槽传递以避免特殊字符解析问题的技巧。
概述
本文介绍如何开发一个美观的作者卡片组件 AuthorCard,用于在 VitePress 中展示作者信息、简介和许可证等内容。
组件需求
- 圆角矩形卡片设计
- 左上角作者头像(支持本地图片和图链)
- 作者名点击跳转链接
- 副名称显示(斜体)
- 简介内容(支持多行文本和链接)
- 许可证显示
- 随机马卡龙色渐变背景
- 悬浮动效
- 响应式适配
组件代码
创建文件 docs/.vitepress/theme/components/AuthorCard.vue:
<script setup lang="ts">
import { computed } from 'vue'
interface Props {
avatar: string
name: string
link?: string
subtitle?: string
license?: string
}
const props = withDefaults(defineProps<Props>(), {
link: '#',
subtitle: '',
license: ''
})
const macaronColors = [
{ bg: 'rgba(255, 182, 193, 0.25)', bgEnd: 'rgba(255, 182, 193, 0.05)' },
{ bg: 'rgba(173, 216, 230, 0.25)', bgEnd: 'rgba(173, 216, 230, 0.05)' },
{ bg: 'rgba(144, 238, 144, 0.25)', bgEnd: 'rgba(144, 238, 144, 0.05)' },
{ bg: 'rgba(255, 218, 185, 0.25)', bgEnd: 'rgba(255, 218, 185, 0.05)' },
{ bg: 'rgba(221, 160, 221, 0.25)', bgEnd: 'rgba(221, 160, 221, 0.05)' },
{ bg: 'rgba(175, 238, 238, 0.25)', bgEnd: 'rgba(175, 238, 238, 0.05)' },
{ bg: 'rgba(255, 255, 224, 0.25)', bgEnd: 'rgba(255, 255, 224, 0.05)' },
{ bg: 'rgba(230, 230, 250, 0.25)', bgEnd: 'rgba(230, 230, 250, 0.05)' },
]
const randomColor = computed(() => {
const index = Math.floor(Math.random() * macaronColors.length)
return macaronColors[index]
})
</script>
<template>
<div class="author-card" :style="{ background: `linear-gradient(180deg, ${randomColor.bg} 0%, ${randomColor.bgEnd} 100%)` }">
<div class="avatar">
<img :src="avatar" :alt="name" />
</div>
<div class="content">
<a v-if="link" :href="link" class="name" target="_blank">{{ name }}</a>
<span v-else class="name">{{ name }}</span>
<span v-if="subtitle" class="subtitle">{{ subtitle }}</span>
<div v-if="$slots.description" class="description">
<slot name="description" />
</div>
<span v-if="license" class="license">许可证:{{ license }}</span>
</div>
</div>
</template>
<style scoped lang="scss">
.author-card {
display: flex;
gap: 16px;
padding: 16px 20px;
border-radius: 12px;
border: none;
margin: 1.5rem 0;
backdrop-filter: blur(10px);
transition: transform 0.3s ease, box-shadow 0.3s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}
}
.avatar {
flex-shrink: 0;
width: 56px;
height: 56px;
border-radius: 50%;
overflow: hidden;
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
.content {
flex: 1;
min-width: 0;
}
.name {
display: block;
font-size: 1.1rem;
font-weight: 600;
color: var(--vp-c-text-1);
text-decoration: none;
transition: color 0.3s ease;
&:hover {
color: var(--vp-c-brand);
}
&::before {
display: none !important;
}
}
.subtitle {
display: block;
font-size: 0.9rem;
color: var(--vp-c-text-3);
font-style: italic;
}
.description {
margin: 8px 0;
font-size: 0.95rem;
color: var(--vp-c-text-2);
line-height: 1.5;
}
.license {
display: inline-block;
font-size: 0.8rem;
color: var(--vp-c-text-2);
padding: 2px 8px;
background: rgba(0, 0, 0, 0.1);
border-radius: 4px;
}
@media (max-width: 640px) {
.author-card {
padding: 12px 16px;
gap: 12px;
}
.avatar {
width: 48px;
height: 48px;
}
.name {
font-size: 1rem;
}
.description {
font-size: 0.9rem;
}
}
</style>注册组件
在 docs/.vitepress/theme/index.ts 中注册组件:
import AuthorCard from "./components/AuthorCard.vue";
export default {
enhanceApp({ app }: { app: any }) {
app.component('AuthorCard', AuthorCard);
},
};使用方法
基础用法
<AuthorCard
avatar="/avatar.png"
name="作者名称"
link="https://example.com"
subtitle="副名称"
license="MIT"
>
<template #description>
这里是多行简介内容
</template>
</AuthorCard>完整示例
<AuthorCard
avatar="/mcoo/avatar.png"
name="凉宫山风"
link="https://space.bilibili.com/39934370"
subtitle="Y_Suzumiya"
license="CC BY-NC-SA 4.0"
>
<template #description>
来自@方块工程师杯官方 比赛瑞士轮第四轮的赛博马场,快来和xdm来一场紧张刺激的赛马罢*<br><br>
感兴趣的兄弟们可以进群一起赤石awa~:927868234<br><br>
----------------------------<br><br>
Mcoo服务器基于 Fabric 1.21 的原版生存玩法运行...
</template>
</AuthorCard>关键实现点
1. 使用插槽传递长文本
当需要传递包含特殊字符的多行文本时,使用 prop 传值会导致解析错误。解决方案是使用 Vue 插槽:
<div v-if="$slots.description" class="description">
<slot name="description" />
</div>使用时通过 <template #description> 传递内容:
<AuthorCard ...>
<template #description>
多行文本内容...
</template>
</AuthorCard>2. 随机马卡龙色背景
使用 computed 和 Math.random() 实现每次渲染随机选择颜色:
const macaronColors = [
{ bg: 'rgba(255, 182, 193, 0.25)', bgEnd: 'rgba(255, 182, 193, 0.05)' },
// ... 更多颜色
]
const randomColor = computed(() => {
const index = Math.floor(Math.random() * macaronColors.length)
return macaronColors[index]
})背景使用渐变,从顶部颜色到底部透明:
:style="{ background: `linear-gradient(180deg, ${randomColor.bg} 0%, ${randomColor.bgEnd} 100%)` }"3. 屏蔽链接图标
由于我们之前为外部链接添加了图标,所以需要通过 CSS 屏蔽:
.name {
&::before {
display: none !important;
}
}4. 响应式适配
使用媒体查询调整移动端样式:
@media (max-width: 640px) {
.author-card {
padding: 12px 16px;
gap: 12px;
}
.avatar {
width: 48px;
height: 48px;
}
}组件参数说明
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| avatar | 头像图片地址 | string | - |
| name | 作者名称 | string | - |
| link | 作者链接 | string | # |
| subtitle | 副名称(斜体) | string | '' |
| license | 许可证文本 | string | '' |
| 插槽 | 说明 |
|---|---|
| description | 简介内容,支持 HTML 标签 |
本文由 DoubleSpirit121 原创
采用 CC BY-NC-SA 4.0 协议进行许可
TAGS:
VitePress 1.6.3
0 评论