#
VitePress真是太好用了
2026-02-11
更好用的团队页面
本文详细介绍了如何开发一个更好用的 VitePress 团队页面组件。原生的 VPTeamMembers 组件存在两个痛点:GitHub 头像在国内网络环境下加载缓慢,以及添加链接图标需要编写大段 SVG 代码。通过使用本地资源文件、TypeScript 类型定义和 CSS 悬浮动效,我们开发了一个轻量级、易维护的 TeamMembers 组件。该组件支持灵活的成员管理、多种链接平台图标自动映射,并实现了管理员/普通成员和在职/离职成员的自动分类显示功能。
前言
在 VitePress 中,官方提供了 VPTeamMembers 组件来展示团队成员。然而在实际使用中,我发现它存在两个明显的痛点:
- 头像加载缓慢 - 直接引用 GitHub 头像源,国内网络环境下经常加载失败或超时
- 添加链接图标繁琐 - 需要手动编写大段 SVG 代码,不仅难以维护,还影响文章可读性
为了解决这些问题,我开发了一个更加易用的团队页面组件。
实现思路
核心目标
- 使用本地头像图片,告别加载慢的问题
- 链接图标也使用本地 SVG 文件
- 支持灵活的成员管理(管理员/普通成员、在职/离职)
- 添加悬浮动效提升视觉体验
技术方案
- 创建一个可复用的 Vue 组件
TeamMembers.vue - 使用 TypeScript 定义成员数据结构
- 通过 props 接收标题、描述和成员列表
- 使用 CSS 实现卡片悬浮效果
组件开发
目录结构
docs/
├── public/
│ ├── mcoo/ # 成员头像目录
│ │ ├── DoubleSpirit121.png
│ │ └── RSEGordon.png
│ └── icons/ # 链接图标目录
│ ├── github.svg
│ ├── bilibili.svg
│ └── ...
└── .vitepress/
└── theme/
└── components/
└── TeamMembers.vue组件代码
首先创建 TeamMembers.vue 组件:
<script setup lang="ts">
interface Member {
name: string
avatar: string
title: string
role: 'admin' | 'member'
active: boolean
links: {
platform: 'github' | 'bilibili' | 'qq' | 'wechat' | 'youtube' | 'weibo' | 'aifadian'
url: string
}[]
}
const props = defineProps<{
title: string
description?: string
members: Member[]
}>()
const iconMap: Record<string, string> = {
github: '/icons/github.svg',
bilibili: '/icons/bilibili.svg',
qq: '/icons/QQ.svg',
wechat: '/icons/wechat.svg',
youtube: '/icons/youtube.svg',
weibo: '/icons/weibo.svg',
aifadian: '/icons/aifadian.svg',
}
</script>
<template>
<div class="team-section">
<h2 class="section-title">{{ title }}</h2>
<p v-if="description" class="section-desc">{{ description }}</p>
<div class="member-grid">
<div
v-for="(member, index) in members"
:key="index"
class="member-card"
:class="{
'is-admin': member.role === 'admin',
'is-inactive': member.active === false
}"
>
<div class="card-inner">
<div class="avatar-wrapper">
<img :src="member.avatar" :alt="member.name" class="avatar" />
</div>
<div class="member-info">
<h3 class="member-name">{{ member.name }}</h3>
<p class="member-title">{{ member.title }}</p>
<div class="member-links">
<a
v-for="link in member.links"
:key="link.platform"
:href="link.url"
target="_blank"
class="link-icon"
>
<img :src="iconMap[link.platform]" :alt="link.platform" />
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</template>样式设计
为组件添加悬浮动效和响应式布局:
.member-card {
border-radius: 12px;
background: var(--vp-c-bg-soft);
transition: all 0.3s ease;
}
.member-card:hover {
transform: translateY(-4px);
box-shadow: 0 8px 30px rgba(var(--vp-c-brand-rgb), 0.15);
}
.member-card:hover .avatar {
transform: scale(1.05);
}
.member-grid {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
max-width: 1200px;
}全局注册组件
在 index.ts 中注册组件,使其可以在 Markdown 文件中直接使用:
import TeamMembers from "./components/TeamMembers.vue";
export default {
extends: Teek,
enhanceApp({ app }: { app: any }) {
app.component('TeamMembers', TeamMembers);
},
}使用方法
准备资源文件
- 将成员头像图片放入
docs/public/mcoo/目录 - 将链接图标放入
docs/public/icons/目录(GitHub、Bilibili、QQ 等图标已准备)
编写团队页面
在 Markdown 文件中使用组件:
---
title: 团队介绍
permalink: /team
layout: page
article: false
sidebar: false
---
<script setup lang="ts">
const teamMembers = [
{
name: '双灵',
avatar: '/mcoo/DoubleSpirit121.png',
title: '创始人 & 开发者',
role: 'admin',
active: true,
links: [
{ platform: 'github', url: 'https://github.com/GeminiAlpha-1' },
{ platform: 'bilibili', url: 'https://space.bilibili.com/1323019347' }
]
},
{
name: '戈登',
avatar: '/mcoo/RSEGordon.png',
title: '联合创始人',
role: 'admin',
active: true,
links: [
{ platform: 'github', url: 'https://github.com/RSEGordon' },
{ platform: 'bilibili', url: 'https://space.bilibili.com/339232775' }
]
},
{
name: '新成员',
avatar: '/mcoo/default.png',
title: '成员',
role: 'member',
active: false, // 设置为 false 自动移到最后
links: [
{ platform: 'github', url: 'https://github.com/' }
]
}
]
</script>
<div class="team-container">
<div class="team-header">
<h1>Mcoo 墨客小筑</h1>
<p class="team-slogan">人活一世,草木一秋,开心即可,不必讨好。</p>
</div>
<TeamMembers
title="核心成员"
description="主要维护者和开发者。"
:members="teamMembers.filter(m => m.role === 'admin' && m.active !== false)"
/>
<TeamMembers
title="团队成员"
description="排名不分先后,感谢以下成员的贡献。"
:members="teamMembers.filter(m => m.role === 'member' && m.active !== false)"
/>
<div v-if="teamMembers.some(m => m.active === false)" class="inactive-section">
<TeamMembers
title="曾任成员"
description="感谢曾经的陪伴。"
:members="teamMembers.filter(m => m.active === false)"
/>
</div>
</div>功能特性
支持的链接平台
| 平台 | 参数值 | 图标文件 |
|---|---|---|
| GitHub | github | /icons/github.svg |
| 哔哩哔哩 | bilibili | /icons/bilibili.svg |
qq | /icons/QQ.svg | |
| 微信 | wechat | /icons/wechat.svg |
| YouTube | youtube | /icons/youtube.svg |
| 微博 | weibo | /icons/weibo.svg |
| 爱发电 | aifadian | /icons/aifadian.svg |
成员角色
admin- 核心成员,卡片头像显示为 100pxmember- 普通成员,卡片头像显示为 80px
离职成员管理
将成员的 active 设为 false,该成员会自动显示在底部的"曾任成员"区域,无需手动移动位置。
视觉效果
- 鼠标悬停时卡片微微上浮
- 卡片四周产生辉光效果
- 头像图片放大动画
- 响应式布局适配移动端
总结
通过使用本地资源,我们解决了 GitHub 头像加载慢的问题;通过图标映射表,我们简化了链接图标的添加方式。这种方案不仅提升了页面加载速度,也让后续维护变得更加简单。
添加新成员只需在数组中添加一个对象,无需关心任何样式和布局代码。
本文由 DoubleSpirit121 原创
采用 CC BY-NC-SA 4.0 协议进行许可
TAGS:
VitePress 1.6.3
0 评论