Skip to content

Commit 04e3042

Browse files
authored
feat: support mobile view (#652)
1 parent ac2635c commit 04e3042

File tree

3 files changed

+56
-16
lines changed

3 files changed

+56
-16
lines changed

src/components/CodemirrorEditor/EditorHeader/index.vue

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,16 +103,18 @@ function copy() {
103103
</script>
104104

105105
<template>
106-
<header class="header-container h-15 flex items-center justify-between px-5 dark:bg-[#191c20]">
107-
<div class="space-x-2 flex">
106+
<header class="header-container h-15 flex flex-wrap items-center justify-between px-5 dark:bg-[#191c20]">
107+
<!-- 左侧菜单:移动端隐藏 -->
108+
<div class="space-x-2 hidden sm:flex">
108109
<Menubar class="menubar">
109110
<FileDropdown />
110111

111112
<MenubarMenu>
112113
<MenubarTrigger> 格式 </MenubarTrigger>
113114
<MenubarContent class="w-60" align="start">
114115
<MenubarCheckboxItem
115-
v-for="{ label, kbd, emitArgs } in formatItems" :key="label"
116+
v-for="{ label, kbd, emitArgs } in formatItems"
117+
:key="label"
116118
@click="emitArgs[0] === 'addFormat' ? $emit(emitArgs[0], emitArgs[1]) : $emit(emitArgs[0])"
117119
>
118120
{{ label }}
@@ -141,7 +143,9 @@ function copy() {
141143
</Menubar>
142144
</div>
143145

144-
<div class="space-x-2 flex">
146+
<!-- 右侧操作区:移动端保留核心按钮 -->
147+
<div class="space-x-2 flex flex-wrap">
148+
<!-- 展开/收起左侧内容栏 -->
145149
<TooltipProvider :delay-duration="200">
146150
<Tooltip>
147151
<TooltipTrigger as-child>
@@ -156,11 +160,13 @@ function copy() {
156160
</Tooltip>
157161
</TooltipProvider>
158162

163+
<!-- 暗色切换 -->
159164
<Button variant="outline" @click="toggleDark()">
160165
<Moon v-show="isDark" class="size-4" />
161166
<Sun v-show="!isDark" class="size-4" />
162167
</Button>
163168

169+
<!-- 复制按钮组 -->
164170
<div class="space-x-1 bg-background text-background-foreground mx-2 flex items-center border rounded-md">
165171
<Button variant="ghost" class="shadow-none" @click="copy">
166172
复制
@@ -189,8 +195,10 @@ function copy() {
189195
</DropdownMenu>
190196
</div>
191197

192-
<PostInfo />
198+
<!-- 文章信息(移动端隐藏) -->
199+
<PostInfo class="hidden sm:inline-flex" />
193200

201+
<!-- 设置按钮 -->
194202
<Button variant="outline" @click="store.isOpenRightSlider = !store.isOpenRightSlider">
195203
<Settings class="size-4" />
196204
</Button>

src/stores/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ export const useStore = defineStore(`store`, () => {
102102
},
103103
],
104104
createDatetime: new Date(),
105-
updateDatetime: new Date()
105+
updateDatetime: new Date(),
106106
},
107107
])
108108

@@ -131,7 +131,7 @@ export const useStore = defineStore(`store`, () => {
131131
},
132132
],
133133
createDatetime: new Date(),
134-
updateDatetime: new Date()
134+
updateDatetime: new Date(),
135135
}) - 1
136136
}
137137

src/views/CodemirrorEditor.vue

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
} from '@/utils'
1010
import fileApi from '@/utils/file'
1111
import CodeMirror from 'codemirror'
12-
import { List } from 'lucide-vue-next'
12+
import { Eye, List, Pen } from 'lucide-vue-next'
1313
1414
const store = useStore()
1515
const displayStore = useDisplayStore()
@@ -36,6 +36,31 @@ const {
3636
const isImgLoading = ref(false)
3737
const timeout = ref<NodeJS.Timeout>()
3838
39+
const isMobile = ref(false)
40+
const showEditor = ref(true)
41+
42+
// 判断是否为移动端(初始 + resize 响应)
43+
function handleResize() {
44+
isMobile.value = window.innerWidth <= 768
45+
}
46+
47+
onMounted(() => {
48+
handleResize()
49+
window.addEventListener(`resize`, handleResize)
50+
setTimeout(() => {
51+
leftAndRightScroll()
52+
}, 300)
53+
})
54+
55+
onBeforeUnmount(() => {
56+
window.removeEventListener(`resize`, handleResize)
57+
})
58+
59+
// 切换编辑/预览视图(仅限移动端)
60+
function toggleView() {
61+
showEditor.value = !showEditor.value
62+
}
63+
3964
const preview = ref<HTMLDivElement | null>(null)
4065
4166
// 使浏览区与编辑区滚动条建立同步联系
@@ -83,12 +108,6 @@ function leftAndRightScroll() {
83108
editor.value!.on(`scroll`, editorScrollCB)
84109
}
85110
86-
onMounted(() => {
87-
setTimeout(() => {
88-
leftAndRightScroll()
89-
}, 300)
90-
})
91-
92111
// 更新编辑器
93112
function onEditorRefresh() {
94113
editorRefresh()
@@ -401,6 +420,7 @@ const isOpenHeadingSlider = ref(false)
401420
<div class="container-main-section border-radius-10 relative flex flex-1 overflow-hidden border-1">
402421
<PostSlider />
403422
<div
423+
v-show="!isMobile || (isMobile && showEditor)"
404424
ref="codeMirrorWrapper"
405425
class="codeMirror-wrapper flex-1"
406426
:class="{
@@ -458,7 +478,10 @@ const isOpenHeadingSlider = ref(false)
458478
</ContextMenuContent>
459479
</ContextMenu>
460480
</div>
461-
<div class="relative flex-1">
481+
<div
482+
v-show="!isMobile || (isMobile && !showEditor)"
483+
class="relative flex-1"
484+
>
462485
<div
463486
id="preview"
464487
ref="preview"
@@ -475,7 +498,6 @@ const isOpenHeadingSlider = ref(false)
475498
</div>
476499
</div>
477500
</div>
478-
479501
<BackTop target="preview" :right="40" :bottom="40" />
480502
</div>
481503
<div
@@ -506,6 +528,15 @@ const isOpenHeadingSlider = ref(false)
506528
字数 {{ readingTime?.words }}, 阅读大约需 {{ Math.ceil(readingTime?.minutes ?? 0) }} 分钟
507529
</footer>
508530

531+
<button
532+
v-if="isMobile"
533+
class="bg-primary fixed bottom-16 right-6 z-50 flex items-center justify-center rounded-full p-3 text-white shadow-lg transition active:scale-95 hover:scale-105 dark:bg-gray-700 dark:text-white dark:ring-2 dark:ring-white/30"
534+
aria-label="切换编辑/预览"
535+
@click="toggleView"
536+
>
537+
<component :is="showEditor ? Eye : Pen" class="h-5 w-5" />
538+
</button>
539+
509540
<UploadImgDialog @upload-image="uploadImage" />
510541

511542
<InsertFormDialog />
@@ -589,5 +620,6 @@ const isOpenHeadingSlider = ref(false)
589620
590621
.codeMirror-wrapper {
591622
overflow-x: auto;
623+
height: 100%;
592624
}
593625
</style>

0 commit comments

Comments
 (0)