提取组件
This commit is contained in:
parent
44ceb8ce2b
commit
b60faf5518
@ -1,6 +1,6 @@
|
||||
export default {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
|
13
src/api/git.ts
Normal file
13
src/api/git.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import {request} from "@/utils/network.ts";
|
||||
|
||||
const TOKEN = "fb8aec429ea7d0a36f7238dbffda9d2d66c7b045"
|
||||
|
||||
export async function getActivity() {
|
||||
return request({
|
||||
url: '/git/api/v1/users/cantyonion/activities/feeds',
|
||||
method: 'get',
|
||||
headers: {
|
||||
Authorization: ` ${TOKEN}`
|
||||
}
|
||||
})
|
||||
}
|
27
src/components/card/CardTitle.vue
Normal file
27
src/components/card/CardTitle.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
title: string
|
||||
mainColor: string
|
||||
subColor: string
|
||||
url: string
|
||||
icon: string[]
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="mb-4 flex justify-between text-2xl font-bold text-white">
|
||||
<div :class="mainColor" class="w-max overflow-hidden rounded-2xl bg-rose-500 flex justify-center items-center">
|
||||
<div :class="[subColor]" class="rounded-2xl px-4 py-2 w-14 text-center flex justify-center items-center h-full">
|
||||
<font-awesome-icon :icon="icon"/>
|
||||
</div>
|
||||
<span class="px-4">{{ title }}</span>
|
||||
</div>
|
||||
<a :class="[mainColor]" :href="url" class="rounded-2xl px-4 py-2">
|
||||
<font-awesome-icon :icon="['fas', 'chevron-right']"/>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
42
src/components/card/SectionCard.vue
Normal file
42
src/components/card/SectionCard.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
loading: boolean
|
||||
error: boolean
|
||||
empty: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits(['reload'])
|
||||
|
||||
const handleReload = () => {
|
||||
emit('reload')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div :class="{'justify-center': (empty || error)}" class="container flex">
|
||||
<!-- 加载骨架 -->
|
||||
<div v-if="loading" class="h-56 w-full text-2xl font-bold">
|
||||
<slot name="skeleton">
|
||||
<div class="grid w-full grid-cols-1 gap-4 overflow-hidden sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
||||
<div v-for="index of 3" :key="index" class="h-56 animate-pulse rounded-2xl bg-gray-200"></div>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
<div v-else>
|
||||
<!-- 错误处理 -->
|
||||
<div v-if="error" class="flex flex-col h-56 items-center justify-center" @click="handleReload">
|
||||
<span class="mb-4 text-8xl">❌</span>
|
||||
<span class="text-center text-2xl font-bold">载入错误</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<!-- 正式内容 -->
|
||||
<span v-if="empty" class="text-2xl font-bold">最近没有动态</span>
|
||||
<slot v-else name="default"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
13
src/main.ts
13
src/main.ts
@ -6,11 +6,20 @@ import router from "@/router";
|
||||
import {library} from '@fortawesome/fontawesome-svg-core'
|
||||
import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome'
|
||||
import {faClock} from '@fortawesome/free-regular-svg-icons'
|
||||
import {faXmark, faBlog, faGauge, faCodeBranch, faCloud, faChevronRight} from '@fortawesome/free-solid-svg-icons'
|
||||
import {
|
||||
faXmark,
|
||||
faBlog,
|
||||
faGauge,
|
||||
faCodeBranch,
|
||||
faCloud,
|
||||
faChevronRight,
|
||||
faCodeCommit
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import {faWeibo, faQq, faGithubAlt, faSteamSymbol} from '@fortawesome/free-brands-svg-icons'
|
||||
|
||||
library.add(
|
||||
faClock, faXmark, faBlog, faGauge, faCodeBranch, faCloud, faWeibo, faQq, faGithubAlt, faSteamSymbol, faChevronRight
|
||||
faClock, faXmark, faBlog, faGauge, faCodeBranch, faCloud, faWeibo, faQq, faGithubAlt, faSteamSymbol, faChevronRight,
|
||||
faCodeCommit
|
||||
)
|
||||
|
||||
createApp(App).use(router).component('font-awesome-icon', FontAwesomeIcon).mount('#app')
|
||||
|
@ -2,13 +2,20 @@
|
||||
import {computed, onMounted, ref} from "vue";
|
||||
import ArticleCard from "@/components/card/ArticleCard.vue";
|
||||
import {getBlogRecentPost} from "@/api/blog.ts";
|
||||
// import ArticleDigestViewer from "@/components/card/ArticleDigestViewer.vue";
|
||||
import NavBar from "@/components/nav/NavBar.vue";
|
||||
import IntroCard from "@/components/card/IntroCard.vue";
|
||||
import CardTitle from "@/components/card/CardTitle.vue";
|
||||
import SectionCard from "@/components/card/SectionCard.vue";
|
||||
|
||||
const recentPosts = ref<IPost[] | null>(null);
|
||||
const isLoading = ref(true);
|
||||
const isError = ref(false);
|
||||
const isLoading = ref({
|
||||
blog: true,
|
||||
git: true
|
||||
});
|
||||
const isError = ref({
|
||||
blog: false,
|
||||
git: false
|
||||
});
|
||||
|
||||
const hasPosts = computed(() => (recentPosts.value ?? []).length > 0);
|
||||
const postsData = computed(() => {
|
||||
@ -20,13 +27,13 @@ const postsData = computed(() => {
|
||||
|
||||
const reloadPosts = async () => {
|
||||
try {
|
||||
isLoading.value = true
|
||||
isLoading.value.blog = true
|
||||
const postData = await getBlogRecentPost();
|
||||
recentPosts.value = postData.data.dataSet
|
||||
isLoading.value = false
|
||||
isLoading.value.blog = false
|
||||
} catch (e) {
|
||||
isLoading.value = false
|
||||
isError.value = true
|
||||
isLoading.value.blog = false
|
||||
isError.value.blog = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,10 +41,10 @@ onMounted(async () => {
|
||||
try {
|
||||
const postData = await getBlogRecentPost();
|
||||
recentPosts.value = postData.data.dataSet
|
||||
isLoading.value = false
|
||||
isLoading.value.blog = false
|
||||
} catch (e) {
|
||||
isLoading.value = false
|
||||
isError.value = true
|
||||
isLoading.value.blog = false
|
||||
isError.value.blog = true
|
||||
}
|
||||
})
|
||||
</script>
|
||||
@ -49,44 +56,28 @@ onMounted(async () => {
|
||||
<!-- 个人介绍 -->
|
||||
<intro-card/>
|
||||
|
||||
<div class="w-full px-4 sm:px-0">
|
||||
<!-- 博客部分 -->
|
||||
<section class="w-full px-4 sm:px-0">
|
||||
<!-- 标题部分 -->
|
||||
<div class="mb-4 flex justify-between text-2xl font-bold text-white">
|
||||
<div class="w-max overflow-hidden rounded-2xl bg-rose-500">
|
||||
<div class="inline-block rounded-2xl bg-rose-600 px-4 py-2">
|
||||
<font-awesome-icon :icon="['fas', 'blog']"/>
|
||||
<card-title :icon="['fas', 'blog']" main-color="bg-rose-500" sub-color="bg-rose-600" title="最新博文"
|
||||
url="/blog/"/>
|
||||
|
||||
<section-card :empty="!hasPosts" :error="isError.blog" :loading="isLoading.blog" @reload="reloadPosts">
|
||||
<template v-slot:default>
|
||||
<div class="grid w-full grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
||||
<article-card v-for="item in postsData" :key="item.cid" :post="item"/>
|
||||
</div>
|
||||
<span class="px-4">最新博文</span>
|
||||
</div>
|
||||
<a class="rounded-2xl bg-rose-500 px-4 py-2" href="/blog/">
|
||||
<font-awesome-icon :icon="['fas', 'chevron-right']"/>
|
||||
</a>
|
||||
</div>
|
||||
<!-- 内容 -->
|
||||
<div :class="{'justify-center': (!hasPosts || isError)}" class="container flex">
|
||||
<div v-if="isLoading" class="h-56 w-full text-2xl font-bold">
|
||||
<div
|
||||
class="grid w-full grid-cols-1 gap-4 overflow-hidden sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
||||
<div v-for="index of 3" :key="index" class="h-56 animate-pulse rounded-2xl bg-gray-200"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-if="isError" class="flex flex-col" @click="reloadPosts">
|
||||
<span class="text-8xl mb-4">❌</span>
|
||||
<span class="text-2xl font-bold text-center">载入错误</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<span v-if="!hasPosts" class="text-2xl font-bold">最近没有动态</span>
|
||||
<div v-else class="grid w-full grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
||||
<article-card v-for="item in postsData" :key="item.cid" :post="item"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</section-card>
|
||||
</section>
|
||||
|
||||
<!-- Git部分 -->
|
||||
<section class="w-full px-4 sm:px-0 my-4">
|
||||
<card-title :icon="['fas', 'code-commit']" main-color="bg-green-500" sub-color="bg-green-600" title="最近活动"
|
||||
url="/git/"/>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<!-- <article-digest-viewer/>-->
|
||||
|
||||
<footer class="mt-8 flex w-full items-end bg-white py-4 min-h-48">
|
||||
<div class="container mx-auto">
|
||||
|
Loading…
x
Reference in New Issue
Block a user