forked from Snailclimb/JavaGuide-Interview
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathLayoutToggle.vue
More file actions
142 lines (126 loc) · 3.2 KB
/
LayoutToggle.vue
File metadata and controls
142 lines (126 loc) · 3.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
<template>
<button
class="layout-toggle-btn"
:class="{ 'is-hidden': isHidden }"
:title="isHidden ? '退出沉浸式阅读' : '沉浸式阅读'"
@click="toggleLayout"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path
v-if="!isHidden"
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"
/>
<path
v-else
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"
/>
</svg>
<span class="btn-text">{{ isHidden ? "退出沉浸" : "沉浸阅读" }}</span>
</button>
</template>
<script setup lang="ts">
import { ref, onMounted, watch, computed } from "vue";
import { usePageData } from "vuepress/client";
const isHidden = ref(false);
const pageData = usePageData();
const STORAGE_KEY = "javaguide-interview-layout-hidden";
const IMMERSIVE_TITLE = "JavaGuide 面试题 - 沉浸式阅读中";
// 计算当前页面的原始标题
const originalTitle = computed(() => {
const title = pageData.value.title;
const siteTitle = "JavaGuide 面试题";
return title ? `${title} | ${siteTitle}` : siteTitle;
});
const toggleLayout = () => {
isHidden.value = !isHidden.value;
};
// 更新浏览器标题
const updateBrowserTitle = (hidden: boolean) => {
if (typeof document === "undefined") return;
document.title = hidden ? IMMERSIVE_TITLE : originalTitle.value;
};
// 应用隐藏状态
const applyHiddenState = (hidden: boolean) => {
if (typeof document === "undefined") return;
document.documentElement.classList.toggle("layout-hidden", hidden);
updateBrowserTitle(hidden);
};
// 监听沉浸模式状态变化
watch(isHidden, (newVal) => {
applyHiddenState(newVal);
localStorage?.setItem(STORAGE_KEY, String(newVal));
});
// 监听页面切换,更新标题
watch(
() => pageData.value.path,
() => {
if (isHidden.value) {
updateBrowserTitle(true);
}
},
);
onMounted(() => {
const saved = localStorage?.getItem(STORAGE_KEY);
if (saved === "true") {
isHidden.value = true;
applyHiddenState(true);
}
});
</script>
<style lang="scss" scoped>
.layout-toggle-btn {
position: fixed;
right: 20px;
bottom: 150px;
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
height: 36px;
padding: 0 14px;
font-size: 13px;
color: var(--vp-c-text);
background: var(--vp-c-bg);
border: 1px solid var(--vp-c-border);
border-radius: 18px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
cursor: pointer;
transition: all 0.3s ease;
white-space: nowrap;
&:hover {
color: var(--vp-c-accent);
border-color: var(--vp-c-accent);
transform: scale(1.02);
}
&.is-hidden {
background: var(--vp-c-accent);
color: #fff;
border-color: var(--vp-c-accent);
}
svg {
width: 16px;
height: 16px;
flex-shrink: 0;
}
.btn-text {
font-weight: 500;
}
}
// 移动端和平板隐藏按钮
@media (max-width: 959px) {
.layout-toggle-btn {
display: none;
}
}
</style>