📅 我们继续 50 个小项目挑战!—— GithubProfies
组件
仓库地址:https://github.com/SunACong/50-vue-projects
项目预览地址:https://50-vue-projects.vercel.app/
使用 Vue 3 的 Composition API(<script setup>
)结合 TailwindCSS 创建一个Github 用户信息展示组件。用户可以在输入框中搜索用户名,组件将通过 Github Public API 获取用户信息和其仓库数据并展示。
🎯 组件目标
- 用户输入 Github 用户名并提交
- 通过 Github API 获取用户信息
- 获取用户的公开仓库并展示
- 支持错误提示(如用户不存在)
- 使用 Vue 3 Composition API 管理状态
- 使用 TailwindCSS 构建响应式 UI
- 展示清晰的用户信息与仓库列表
⚙️ 技术实现点
技术点 | 描述 |
---|---|
Vue 3 <script setup> |
使用响应式变量管理用户信息、仓库、错误状态 |
ref 响应式变量 |
控制 username 、user 、repos 和 error |
v-model |
绑定输入框内容 |
@submit.prevent |
阻止默认表单提交行为并触发请求 |
fetch() |
请求 Github 用户信息与仓库数据 |
错误处理 | 使用 try/catch 捕获请求错误 |
TailwindCSS 布局类 | 构建全屏布局、卡片样式、响应式设计 |
动态条件渲染 v-if , v-else-if |
根据状态显示错误、用户信息或空状态 |
🧱 组件实现
模板结构 <template>
<template>
<div class="flex min-h-screen flex-col items-center justify-center bg-[#2a2a72] p-4 font-sans text-white">
<form @submit.prevent="handleSubmit" class="mb-8 w-full max-w-xl">
<input
v-model="username"
type="text"
placeholder="Search a Github User"
class="w-full rounded-lg bg-[#4c2885] p-4 text-white shadow-lg placeholder:text-[#bbb] focus:outline-none" />
</form>
<!-- 错误卡片 -->
<div v-if="error" class="max-w-3xl rounded-2xl bg-[#4c2885] p-6 text-center shadow-lg">
<h1 class="text-xl font-bold">{{ error }}</h1>
</div>
<!-- 用户信息卡片 -->
<div v-else-if="user" class="flex w-full max-w-3xl flex-col rounded-2xl bg-[#4c2885] p-6 shadow-lg md:flex-row">
<div class="flex flex-shrink-0 justify-center">
<img :src="user.avatar_url" :alt="user.name" class="h-36 w-36 rounded-full border-[10px] border-[#2a2a72]" />
</div>
<div class="mt-4 ml-0 flex-grow md:mt-0 md:ml-8">
<h2 class="mb-2 text-2xl font-bold">{{ user.name || user.login }}</h2>
<p v-if="user.bio" class="mb-4">{{ user.bio }}</p>
<ul class="mb-4 flex max-w-md justify-between text-sm">
<li>
{{ user.followers }}
<strong class="ml-1">Followers</strong>
</li>
<li>
{{ user.following }}
<strong class="ml-1">Following</strong>
</li>
<li>
{{ user.public_repos }}
<strong class="ml-1">Repos</strong>
</li>
</ul>
<div class="flex flex-wrap gap-2">
<a v-for="repo in repos.slice(0, 5)" :key="repo.id" :href="repo.html_url" target="_blank"
class="inline-block rounded bg-[#212a72] px-2 py-1 text-xs text-white">
{{ repo.name }}
</a>
</div>
</div>
</div>
</div>
</template>
脚本逻辑 <script setup>
<script setup>
import { ref } from 'vue'
const API_URL = 'https://api.github.com/users/'
const username = ref('')
const user = ref(null)
const repos = ref([])
const error = ref('')
const getUser = async (name) => {
try {
error.value = ''
const res = await fetch(API_URL + name)
if (!res.ok) {
throw new Error('Not Found')
}
user.value = await res.json()
console.log(user.value)
await getRepos(name)
} catch (err) {
error.value = 'No profile with this username'
user.value = null
repos.value = []
}
}
const getRepos = async (name) => {
try {
const res = await fetch(`${API_URL}${name}/repos?sort=created`)
if (!res.ok) {
throw new Error('Repo Fetch Failed')
}
repos.value = await res.json()
} catch (err) {
error.value = 'Problem fetching repos'
}
}
const handleSubmit = () => {
const trimmed = username.value.trim()
if (trimmed) {
getUser(trimmed)
username.value = ''
}
}
</script>
样式部分 <style scoped>
<style scoped>
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap');
:root {
font-family: 'Poppins', sans-serif;
}
</style>
🔍 重点效果实现
✅ 用户信息获取
通过 fetch()
请求 Github API 获取用户信息:
const res = await fetch(API_URL + name)
如果用户不存在,抛出错误并设置提示信息。
💡 获取用户仓库
使用 repos
接口获取用户公开仓库:
const res = await fetch(`${API_URL}${name}/repos?sort=created`)
并在页面上展示前 5 个仓库。
🎮 表单提交处理
使用 @submit.prevent
阻止默认提交行为并触发请求:
<form @submit.prevent="handleSubmit">
输入框使用 v-model
双向绑定用户名:
<input v-model="username" type="text" />
🎨 动态条件渲染
根据状态显示不同的内容:
<div v-if="error">...</div>
<div v-else-if="user">...</div>
🎨 TailwindCSS 样式重点讲解
类名 | 作用 |
---|---|
flex min-h-screen flex-col items-center justify-center |
全屏居中布局 |
bg-[#2a2a72] , text-white |
设置主题颜色 |
rounded-lg , shadow-lg |
输入框与卡片阴影样式 |
border-[10px] border-[#2a2a72] |
头像边框样式 |
flex-wrap gap-2 |
仓库标签自动换行与间距 |
text-xs , rounded , bg-[#212a72] |
仓库标签样式 |
max-w-3xl , md:flex-row |
响应式布局控制 |
这些 TailwindCSS 类帮助我们快速构建了一个美观、响应式的用户信息展示组件。
📁 常量定义 + 组件路由
constants/index.js
添加组件预览常量:
{
id: 28,
title: 'Github Profiles',
image: 'https://50projects50days.com/img/projects-img/28-github-profiles.png',
link: 'GithubProfiles',
},
router/index.js
中添加路由选项:
{
path: '/GithubProfiles',
name: 'GithubProfiles',
component: () => import('@/projects/GithubProfiles.vue'),
},
🏁 总结
基于 Vue 3 和 TailwindCSS 的 Github 用户信息展示组件不仅实现了基本的用户搜索功能,还展示了如何使用 Vue 的响应式能力、异步请求和条件渲染构建一个完整的功能页面。
你可以进一步扩展此组件的功能包括:
- ✅ 添加加载动画(如请求时显示 spinner)
- ✅ 支持分页展示仓库
- ✅ 添加本地缓存(如使用 localStorage)
- ✅ 支持主题切换(暗色/亮色)
- ✅ 将组件封装为
<GithubUserCard />
可复用组件
👉 下一篇,我们将完成Double Click Heart组件,双击点赞的设计。🚀
感谢阅读,欢迎点赞、收藏和分享 😊