mirror of
https://github.com/pengzhanbo/vuepress-theme-plume.git
synced 2026-04-23 10:58:13 +08:00
feat(theme): 新增页面跳转过渡动效
This commit is contained in:
parent
c09cd98075
commit
0fcfe3f0d6
@ -2,6 +2,7 @@
|
||||
import { usePageData } from 'vuepress/client'
|
||||
import type { PlumeThemePageData } from '../../../shared/index.js'
|
||||
import { useThemeLocaleData } from '../../composables/index.js'
|
||||
import TransitionFadeSlideY from '../TransitionFadeSlideY.vue'
|
||||
import PostList from './PostList.vue'
|
||||
import Archives from './Archives.vue'
|
||||
import BlogAside from './BlogAside.vue'
|
||||
@ -16,10 +17,12 @@ const page = usePageData<PlumeThemePageData>()
|
||||
<template>
|
||||
<div class="blog-wrapper">
|
||||
<div class="blog-container" :class="{ 'no-avatar': !theme.avatar }">
|
||||
<BlogNav v-if="!theme.avatar" is-local />
|
||||
<PostList v-if="page.type === 'blog'" />
|
||||
<Tags v-if="page.type === 'blog-tags'" />
|
||||
<Archives v-if="page.type === 'blog-archives'" />
|
||||
<TransitionFadeSlideY>
|
||||
<BlogNav v-if="!theme.avatar" is-local />
|
||||
<PostList v-if="page.type === 'blog'" />
|
||||
<Tags v-if="page.type === 'blog-tags'" />
|
||||
<Archives v-if="page.type === 'blog-archives'" />
|
||||
</TransitionFadeSlideY>
|
||||
<BlogAside />
|
||||
<BlogExtract />
|
||||
</div>
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useThemeLocaleData } from '../../composables/index.js'
|
||||
import SocialLinks from '../SocialLinks.vue'
|
||||
import IconLocation from '../icons/IconLocation.vue'
|
||||
import IconOrganization from '../icons/IconOrganization.vue'
|
||||
|
||||
const theme = useThemeLocaleData()
|
||||
const avatar = computed(() => theme.value.avatar)
|
||||
@ -13,7 +16,18 @@ const avatar = computed(() => theme.value.avatar)
|
||||
</p>
|
||||
<div>
|
||||
<h3>{{ avatar.name }}</h3>
|
||||
<p>{{ avatar.description }}</p>
|
||||
<p v-if="avatar.description" v-html="avatar.description" />
|
||||
<div v-if="avatar.location" class="avatar-location">
|
||||
<IconLocation />
|
||||
<p v-html="avatar.location" />
|
||||
</div>
|
||||
<div v-if="avatar.organization" class="avatar-organization">
|
||||
<IconOrganization />
|
||||
<p v-html="avatar.organization" />
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="theme.social" class="avatar-social">
|
||||
<SocialLinks :links="theme.social" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -44,7 +58,7 @@ const avatar = computed(() => theme.value.avatar)
|
||||
|
||||
.avatar-profile h3 {
|
||||
margin-top: 1.5rem;
|
||||
font-size: 16px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@ -58,4 +72,40 @@ const avatar = computed(() => theme.value.avatar)
|
||||
overflow: hidden;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.avatar-location,
|
||||
.avatar-organization {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 16px;
|
||||
font-size: 14px;
|
||||
color: var(--vp-c-text-3);
|
||||
transition: color var(--t-color);
|
||||
}
|
||||
|
||||
.avatar-location p,
|
||||
.avatar-organization p {
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.avatar-location + .avatar-organization {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.avatar-social {
|
||||
padding-top: 12px;
|
||||
margin-top: 12px;
|
||||
border-top: 1px solid var(--vp-c-divider);
|
||||
transition: border var(--t-color);
|
||||
}
|
||||
|
||||
.avatar-social :deep(.social-link) {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.avatar-social :deep(.social-link:hover) {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -23,7 +23,9 @@ const { hasSidebar } = useSidebar()
|
||||
flex-grow: 1;
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
padding-left: 0;
|
||||
margin: var(--vp-layout-top-height, 0) auto 0;
|
||||
transition: padding-left 0.2s ease;
|
||||
}
|
||||
|
||||
.layout-content.is-home {
|
||||
|
||||
@ -10,6 +10,7 @@ import PageAside from './PageAside.vue'
|
||||
import PageFooter from './PageFooter.vue'
|
||||
import PageMeta from './PageMeta.vue'
|
||||
import EncryptPage from './EncryptPage.vue'
|
||||
import TransitionFadeSlideY from './TransitionFadeSlideY.vue'
|
||||
|
||||
const { hasSidebar, hasAside } = useSidebar()
|
||||
const isDark = useDarkMode()
|
||||
@ -42,24 +43,29 @@ onContentUpdated(() => zoom?.refresh())
|
||||
}"
|
||||
>
|
||||
<div class="container">
|
||||
<div v-if="enableAside" class="aside">
|
||||
<div class="aside-container">
|
||||
<div class="aside-content">
|
||||
<PageAside />
|
||||
<TransitionFadeSlideY>
|
||||
<div v-if="enableAside" :key="page.path" class="aside">
|
||||
<div class="aside-container">
|
||||
<div class="aside-content">
|
||||
<PageAside />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TransitionFadeSlideY>
|
||||
<div class="content">
|
||||
<div class="content-container">
|
||||
<main class="main">
|
||||
<PageMeta />
|
||||
<EncryptPage v-if="!isPageDecrypted" />
|
||||
<template v-else>
|
||||
<Content class="plume-content" />
|
||||
<PageFooter />
|
||||
<PageComment v-if="hasComments" :darkmode="isDark" />
|
||||
</template>
|
||||
</main>
|
||||
<TransitionFadeSlideY>
|
||||
<main :key="page.path" class="main">
|
||||
<PageMeta />
|
||||
<EncryptPage v-if="!isPageDecrypted" />
|
||||
<template v-else>
|
||||
<Content class="plume-content" />
|
||||
|
||||
<PageFooter />
|
||||
<PageComment v-if="hasComments" :darkmode="isDark" />
|
||||
</template>
|
||||
</main>
|
||||
</TransitionFadeSlideY>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -29,30 +29,32 @@ watch(
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<aside
|
||||
v-if="hasSidebar"
|
||||
ref="navEl"
|
||||
class="sidebar-wrapper"
|
||||
:class="{ open }"
|
||||
@click.stop
|
||||
>
|
||||
<div class="curtain" />
|
||||
|
||||
<nav
|
||||
id="SidebarNav"
|
||||
class="nav"
|
||||
aria-labelledby="sidebar-aria-label"
|
||||
tabindex="-1"
|
||||
<Transition name="fade-slide-x" mode="out-in">
|
||||
<aside
|
||||
v-if="hasSidebar"
|
||||
ref="navEl"
|
||||
class="sidebar-wrapper"
|
||||
:class="{ open }"
|
||||
@click.stop
|
||||
>
|
||||
<span id="sidebar-aria-label" class="visually-hidden">
|
||||
Sidebar Navigation
|
||||
</span>
|
||||
<div class="curtain" />
|
||||
|
||||
<div v-for="item in sidebarGroups" :key="item.text" class="group">
|
||||
<SidebarItem :item="item" :depth="0" />
|
||||
</div>
|
||||
</nav>
|
||||
</aside>
|
||||
<nav
|
||||
id="SidebarNav"
|
||||
class="nav"
|
||||
aria-labelledby="sidebar-aria-label"
|
||||
tabindex="-1"
|
||||
>
|
||||
<span id="sidebar-aria-label" class="visually-hidden">
|
||||
Sidebar Navigation
|
||||
</span>
|
||||
|
||||
<div v-for="item in sidebarGroups" :key="item.text" class="group">
|
||||
<SidebarItem :item="item" :depth="0" />
|
||||
</div>
|
||||
</nav>
|
||||
</aside>
|
||||
</Transition>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@ -225,8 +225,21 @@ function onCaretClick() {
|
||||
color: var(--vp-c-text-1);
|
||||
}
|
||||
|
||||
.sidebar-item:not(.collapsible) > .item:hover :deep(.vp-iconify),
|
||||
.sidebar-item:not(.collapsible).has-active > .item > :deep(.vp-iconify) {
|
||||
.sidebar-item.level-0.is-active > .item > :deep(.vp-iconify),
|
||||
.sidebar-item.level-1.is-active > .item > :deep(.vp-iconify),
|
||||
.sidebar-item.level-2.is-active > .item > :deep(.vp-iconify),
|
||||
.sidebar-item.level-3.is-active > .item > :deep(.vp-iconify),
|
||||
.sidebar-item.level-4.is-active > .item > :deep(.vp-iconify),
|
||||
.sidebar-item.level-5.is-active > .item > :deep(.vp-iconify) {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
.sidebar-item.level-0.is-link > .item:hover :deep(.vp-iconify),
|
||||
.sidebar-item.level-1.is-link > .item:hover :deep(.vp-iconify),
|
||||
.sidebar-item.level-2.is-link > .item:hover :deep(.vp-iconify),
|
||||
.sidebar-item.level-3.is-link > .item:hover :deep(.vp-iconify),
|
||||
.sidebar-item.level-4.is-link > .item:hover :deep(.vp-iconify),
|
||||
.sidebar-item.level-5.is-link > .item:hover :deep(.vp-iconify) {
|
||||
color: var(--vp-c-brand-1);
|
||||
}
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ import SkipLink from '../components/SkipLink.vue'
|
||||
import VFooter from '../components/VFooter.vue'
|
||||
import BackToTop from '../components/BackToTop.vue'
|
||||
import EncryptGlobal from '../components/EncryptGlobal.vue'
|
||||
import TransitionFadeSlideY from '../components/TransitionFadeSlideY.vue'
|
||||
import {
|
||||
useCloseSidebarOnEscape,
|
||||
useSidebar,
|
||||
@ -56,17 +57,17 @@ provide('is-sidebar-open', isSidebarOpen)
|
||||
<SkipLink />
|
||||
<Backdrop :show="isSidebarOpen" @click="closeSidebar" />
|
||||
<Nav />
|
||||
<LocalNav
|
||||
:open="isSidebarOpen"
|
||||
:show-outline="isPageDecrypted"
|
||||
@open-menu="openSidebar"
|
||||
/>
|
||||
<LocalNav :open="isSidebarOpen" :show-outline="isPageDecrypted" @open-menu="openSidebar" />
|
||||
<Sidebar :open="isSidebarOpen" />
|
||||
<LayoutContent>
|
||||
<Home v-if="page.frontmatter.home" />
|
||||
<Friends v-else-if="page.frontmatter.friends" />
|
||||
<Blog v-else-if="isBlogLayout" />
|
||||
<Page v-else />
|
||||
<template v-else>
|
||||
<TransitionFadeSlideY>
|
||||
<Friends v-if="page.frontmatter.friends" />
|
||||
<Blog v-else-if="isBlogLayout" />
|
||||
<Page v-else />
|
||||
</TransitionFadeSlideY>
|
||||
</template>
|
||||
<BackToTop />
|
||||
<VFooter />
|
||||
</LayoutContent>
|
||||
|
||||
@ -16,3 +16,34 @@
|
||||
.vp-iconify {
|
||||
margin: 0.3em;
|
||||
}
|
||||
|
||||
/* ----------------- Transition ------------------------ */
|
||||
|
||||
.fade-slide-y-enter-active {
|
||||
transition: all 0.25s ease !important;
|
||||
}
|
||||
|
||||
.fade-slide-y-leave-active {
|
||||
transition: all 0.25s cubic-bezier(0, 1, 0.3, 1) !important;
|
||||
}
|
||||
|
||||
.fade-slide-y-enter-from,
|
||||
.fade-slide-y-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(10px);
|
||||
}
|
||||
|
||||
|
||||
.fade-slide-x-enter-active {
|
||||
transition: all 0.25s ease !important;
|
||||
}
|
||||
|
||||
.fade-slide-x-leave-active {
|
||||
transition: all 0.25s cubic-bezier(0, 1, 0.3, 1) !important;
|
||||
}
|
||||
|
||||
.fade-slide-x-enter-from,
|
||||
.fade-slide-x-leave-to {
|
||||
opacity: 0 !important;
|
||||
transform: translateX(-10px) !important;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user