#

更好用的团队页面

By DoubleSpirit121 1 Views 23 MIN READ 0 Comments
本文详细介绍了如何开发一个更好用的 VitePress 团队页面组件。原生的 VPTeamMembers 组件存在两个痛点:GitHub 头像在国内网络环境下加载缓慢,以及添加链接图标需要编写大段 SVG 代码。通过使用本地资源文件、TypeScript 类型定义和 CSS 悬浮动效,我们开发了一个轻量级、易维护的 TeamMembers 组件。该组件支持灵活的成员管理、多种链接平台图标自动映射,并实现了管理员/普通成员和在职/离职成员的自动分类显示功能。

前言

在 VitePress 中,官方提供了 VPTeamMembers 组件来展示团队成员。然而在实际使用中,我发现它存在两个明显的痛点:

  1. 头像加载缓慢 - 直接引用 GitHub 头像源,国内网络环境下经常加载失败或超时
  2. 添加链接图标繁琐 - 需要手动编写大段 SVG 代码,不仅难以维护,还影响文章可读性

为了解决这些问题,我开发了一个更加易用的团队页面组件。

实现思路

核心目标

  • 使用本地头像图片,告别加载慢的问题
  • 链接图标也使用本地 SVG 文件
  • 支持灵活的成员管理(管理员/普通成员、在职/离职)
  • 添加悬浮动效提升视觉体验

技术方案

  1. 创建一个可复用的 Vue 组件 TeamMembers.vue
  2. 使用 TypeScript 定义成员数据结构
  3. 通过 props 接收标题、描述和成员列表
  4. 使用 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);
  },
}

使用方法

准备资源文件

  1. 将成员头像图片放入 docs/public/mcoo/ 目录
  2. 将链接图标放入 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>

功能特性

支持的链接平台

平台参数值图标文件
GitHubgithub/icons/github.svg
哔哩哔哩bilibili/icons/bilibili.svg
QQqq/icons/QQ.svg
微信wechat/icons/wechat.svg
YouTubeyoutube/icons/youtube.svg
微博weibo/icons/weibo.svg
爱发电aifadian/icons/aifadian.svg

成员角色

  • admin - 核心成员,卡片头像显示为 100px
  • member - 普通成员,卡片头像显示为 80px

离职成员管理

将成员的 active 设为 false,该成员会自动显示在底部的"曾任成员"区域,无需手动移动位置。

视觉效果

  • 鼠标悬停时卡片微微上浮
  • 卡片四周产生辉光效果
  • 头像图片放大动画
  • 响应式布局适配移动端

总结

通过使用本地资源,我们解决了 GitHub 头像加载慢的问题;通过图标映射表,我们简化了链接图标的添加方式。这种方案不仅提升了页面加载速度,也让后续维护变得更加简单。

添加新成员只需在数组中添加一个对象,无需关心任何样式和布局代码。

本文由 DoubleSpirit121 原创

采用 CC BY-NC-SA 4.0 协议进行许可

转载请注明出处:https://blog.mcoo.top/index.php/archives/38/

加入 Mcoo

0 评论

发表评论