Skip to content

Commit a39ea3c

Browse files
committed
feat:加入沉浸阅读功能
响应很多用户的需求,加入了沉浸式阅读功能,隐藏侧边栏和导航,不让别人知道你是在准备面试,适合工作期间使用!
1 parent 15fbf3c commit a39ea3c

File tree

3 files changed

+258
-0
lines changed

3 files changed

+258
-0
lines changed

docs/.vuepress/client.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { defineClientConfig } from "vuepress/client";
2+
import { h } from "vue";
3+
import LayoutToggle from "./components/LayoutToggle.vue";
4+
5+
export default defineClientConfig({
6+
rootComponents: [
7+
// 将切换按钮添加为根组件,会在所有页面显示
8+
() => h(LayoutToggle),
9+
],
10+
});
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
<template>
2+
<button
3+
class="layout-toggle-btn"
4+
:class="{ 'is-hidden': isHidden }"
5+
:title="isHidden ? '退出沉浸式阅读' : '沉浸式阅读'"
6+
@click="toggleLayout"
7+
>
8+
<svg
9+
xmlns="http://www.w3.org/2000/svg"
10+
width="16"
11+
height="16"
12+
viewBox="0 0 24 24"
13+
fill="none"
14+
stroke="currentColor"
15+
stroke-width="2"
16+
stroke-linecap="round"
17+
stroke-linejoin="round"
18+
>
19+
<path
20+
v-if="!isHidden"
21+
d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"
22+
/>
23+
<path
24+
v-else
25+
d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3"
26+
/>
27+
</svg>
28+
<span class="btn-text">{{ isHidden ? "退出沉浸" : "沉浸阅读" }}</span>
29+
</button>
30+
</template>
31+
32+
<script setup lang="ts">
33+
import { ref, onMounted, watch } from "vue";
34+
35+
const isHidden = ref(false);
36+
37+
const STORAGE_KEY = "javaguide-layout-hidden";
38+
39+
const toggleLayout = () => {
40+
isHidden.value = !isHidden.value;
41+
};
42+
43+
// 应用隐藏状态
44+
const applyHiddenState = (hidden: boolean) => {
45+
if (typeof document !== "undefined") {
46+
if (hidden) {
47+
document.documentElement.classList.add("layout-hidden");
48+
} else {
49+
document.documentElement.classList.remove("layout-hidden");
50+
}
51+
}
52+
};
53+
54+
// 监听状态变化
55+
watch(isHidden, (newVal) => {
56+
applyHiddenState(newVal);
57+
// 保存到 localStorage
58+
if (typeof localStorage !== "undefined") {
59+
localStorage.setItem(STORAGE_KEY, String(newVal));
60+
}
61+
});
62+
63+
onMounted(() => {
64+
// 从 localStorage 读取状态
65+
if (typeof localStorage !== "undefined") {
66+
const saved = localStorage.getItem(STORAGE_KEY);
67+
if (saved === "true") {
68+
isHidden.value = true;
69+
applyHiddenState(true);
70+
}
71+
}
72+
});
73+
</script>
74+
75+
<style lang="scss" scoped>
76+
.layout-toggle-btn {
77+
position: fixed;
78+
right: 20px;
79+
bottom: 150px;
80+
z-index: 999;
81+
display: flex;
82+
align-items: center;
83+
justify-content: center;
84+
gap: 6px;
85+
height: 36px;
86+
padding: 0 14px;
87+
font-size: 13px;
88+
color: var(--vp-c-text);
89+
background: var(--vp-c-bg);
90+
border: 1px solid var(--vp-c-border);
91+
border-radius: 18px;
92+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
93+
cursor: pointer;
94+
transition: all 0.3s ease;
95+
white-space: nowrap;
96+
97+
&:hover {
98+
color: var(--vp-c-accent);
99+
border-color: var(--vp-c-accent);
100+
transform: scale(1.02);
101+
}
102+
103+
&.is-hidden {
104+
background: var(--vp-c-accent);
105+
color: #fff;
106+
border-color: var(--vp-c-accent);
107+
}
108+
109+
svg {
110+
width: 16px;
111+
height: 16px;
112+
flex-shrink: 0;
113+
}
114+
115+
.btn-text {
116+
font-weight: 500;
117+
}
118+
}
119+
120+
// 移动端和平板隐藏按钮
121+
@media (max-width: 959px) {
122+
.layout-toggle-btn {
123+
display: none;
124+
}
125+
}
126+
</style>

docs/.vuepress/styles/index.scss

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,125 @@ body {
33
font-size: 16px;
44
}
55
}
6+
7+
// 隐藏布局模式 - 通过 LayoutToggle 组件控制
8+
html.layout-hidden {
9+
// 隐藏顶部导航栏
10+
.vp-navbar {
11+
transform: translateY(-100%) !important;
12+
opacity: 0 !important;
13+
pointer-events: none !important;
14+
}
15+
16+
// 隐藏左侧边栏
17+
.vp-sidebar {
18+
transform: translateX(-100%) !important;
19+
opacity: 0 !important;
20+
pointer-events: none !important;
21+
width: 0 !important;
22+
}
23+
24+
// 侧边栏包装器
25+
.vp-sidebar-wrapper,
26+
.sidebar-wrapper {
27+
width: 0 !important;
28+
min-width: 0 !important;
29+
padding: 0 !important;
30+
margin: 0 !important;
31+
}
32+
33+
// 隐藏右侧目录 (TOC)
34+
.vp-toc-placeholder,
35+
.toc-wrapper,
36+
.vp-toc,
37+
aside.vp-toc,
38+
.toc {
39+
display: none !important;
40+
width: 0 !important;
41+
}
42+
43+
// 主容器调整 - 移除左侧 padding/margin
44+
.theme-container {
45+
padding-left: 0 !important;
46+
padding-right: 0 !important;
47+
48+
.vp-page {
49+
padding-left: 2rem !important;
50+
padding-right: 2rem !important;
51+
padding-top: 1rem !important;
52+
margin-left: 0 !important;
53+
max-width: 100% !important;
54+
width: 100% !important;
55+
transition: all 0.3s ease;
56+
}
57+
}
58+
59+
// 主题内容区域调整 - 让内容更宽
60+
.theme-hope-content,
61+
.vp-page-content,
62+
.vp-content {
63+
max-width: 100% !important;
64+
width: 100% !important;
65+
margin: 0 !important;
66+
padding: 1rem 2rem !important;
67+
}
68+
69+
// 页面容器调整
70+
.vp-page-container {
71+
padding-top: 1rem !important;
72+
padding-left: 0 !important;
73+
padding-right: 0 !important;
74+
max-width: 100% !important;
75+
}
76+
77+
// 确保内容区域居中且宽度适中
78+
.theme-container > main {
79+
margin-left: 0 !important;
80+
padding-left: 0 !important;
81+
max-width: 100% !important;
82+
}
83+
84+
// 响应式调整
85+
@media (min-width: 960px) {
86+
.theme-container .vp-page {
87+
margin-left: 0 !important;
88+
padding-left: 3rem !important;
89+
padding-right: 3rem !important;
90+
}
91+
92+
.theme-hope-content,
93+
.vp-page-content,
94+
.vp-content {
95+
max-width: 100% !important;
96+
padding: 1rem 2rem !important;
97+
}
98+
}
99+
100+
@media (min-width: 1440px) {
101+
.theme-container .vp-page {
102+
margin-left: 0 !important;
103+
padding-left: 4rem !important;
104+
padding-right: 4rem !important;
105+
}
106+
107+
.theme-hope-content,
108+
.vp-page-content,
109+
.vp-content {
110+
max-width: 100% !important;
111+
padding: 1rem 3rem !important;
112+
}
113+
}
114+
}
115+
116+
// 隐藏过渡动画
117+
.vp-navbar,
118+
.vp-sidebar,
119+
.vp-page,
120+
.theme-container .vp-page {
121+
transition:
122+
transform 0.3s ease,
123+
opacity 0.3s ease,
124+
margin 0.3s ease,
125+
padding 0.3s ease,
126+
width 0.3s ease;
127+
}

0 commit comments

Comments
 (0)