Private
Public Access
1
0

重构:文件系统模块化架构,优化应用启动流程

This commit is contained in:
2026-01-28 00:28:54 +08:00
parent 4a9b25a505
commit 8c577f70e7
123 changed files with 32030 additions and 967 deletions

View File

@@ -0,0 +1,287 @@
<template>
<div ref="editorContainer" class="codemirror-editor"></div>
</template>
<script setup>
import { ref, onMounted, watch, onBeforeUnmount } from 'vue'
import { EditorView, lineNumbers, highlightActiveLineGutter } from '@codemirror/view'
import { EditorState } from '@codemirror/state'
import { defaultKeymap, history, historyKeymap } from '@codemirror/commands'
import { javascript } from '@codemirror/lang-javascript'
import { java } from '@codemirror/lang-java'
import { python } from '@codemirror/lang-python'
import { go } from '@codemirror/lang-go'
import { cpp } from '@codemirror/lang-cpp'
import { rust } from '@codemirror/lang-rust'
import { php } from '@codemirror/lang-php'
import { json } from '@codemirror/lang-json'
import { markdown } from '@codemirror/lang-markdown'
import { html } from '@codemirror/lang-html'
import { css } from '@codemirror/lang-css'
import { oneDark } from '@codemirror/theme-one-dark'
import { keymap } from '@codemirror/view'
import { bracketMatching } from '@codemirror/language'
import { useTheme } from '@/composables/useTheme'
// 使用主题系统
const { isDark } = useTheme()
/**
* 文件扩展名到语言的映射
*/
const LANGUAGE_MAP = {
// JavaScript/TypeScript
'js': javascript(),
'jsx': javascript({ jsx: true }),
'ts': javascript({ typescript: true }),
'tsx': javascript({ typescript: true, jsx: true }),
'mjs': javascript(),
'cjs': javascript(),
// JSON
'json': json(),
// Java
'java': java(),
// Python
'py': python(),
// Go
'go': go(),
// C/C++
'c': cpp(),
'cpp': cpp(),
'cc': cpp(),
'cxx': cpp(),
'h': cpp(),
'hpp': cpp(),
'hxx': cpp(),
// Rust
'rs': rust(),
// PHP
'php': php(),
// Markdown
'md': markdown(),
'markdown': markdown(),
// HTML
'html': html(),
'htm': html(),
// CSS
'css': css(),
'scss': css(),
'sass': css(),
'less': css(),
}
const props = defineProps({
modelValue: {
type: String,
required: true
},
fileExtension: {
type: String,
default: ''
}
})
const emit = defineEmits(['update:modelValue'])
const editorContainer = ref(null)
let view = null
// 根据主题动态创建编辑器配置
const createExtensions = () => {
const extensions = [
lineNumbers(),
highlightActiveLineGutter(),
history(),
keymap.of(defaultKeymap),
keymap.of(historyKeymap),
bracketMatching(),
EditorView.updateListener.of((update) => {
if (update.docChanged) {
emit('update:modelValue', update.state.doc.toString())
}
}),
EditorView.theme({
'&': {
height: '100%',
fontSize: '13px'
},
'.cm-scroller': {
overflow: 'auto',
fontFamily: 'Consolas, Monaco, Courier New, monospace'
},
'.cm-content': {
padding: '8px',
minHeight: '100%'
},
'.cm-line': {
padding: '0 0'
},
'&.cm-focused': {
outline: 'none'
}
})
]
// 根据主题添加 One Dark
if (isDark.value) {
extensions.push(oneDark)
}
// 添加语言支持
const langSupport = LANGUAGE_MAP[props.fileExtension]
if (langSupport) {
extensions.push(langSupport)
}
return extensions
}
onMounted(() => {
if (!editorContainer.value) return
const state = EditorState.create({
doc: props.modelValue,
extensions: createExtensions()
})
view = new EditorView({
state,
parent: editorContainer.value
})
})
// 监听外部内容变化
watch(() => props.modelValue, (newValue) => {
if (view && newValue !== view.state.doc.toString()) {
view.dispatch({
changes: {
from: 0,
to: view.state.doc.length,
insert: newValue
}
})
}
})
// 监听主题变化,重新创建编辑器
watch(isDark, () => {
if (view) {
view.destroy()
const state = EditorState.create({
doc: view.state.doc.toString(),
extensions: createExtensions()
})
view = new EditorView({
state,
parent: editorContainer.value
})
}
})
// 监听文件扩展名变化,重新创建编辑器
watch(() => props.fileExtension, () => {
if (view) {
view.destroy()
const state = EditorState.create({
doc: view.state.doc.toString(),
extensions: createExtensions()
})
view = new EditorView({
state,
parent: editorContainer.value
})
}
})
onBeforeUnmount(() => {
if (view) {
view.destroy()
}
})
</script>
<style>
/* 全局语法高亮样式(适用于亮色主题) */
.cm-editor:not(.cm-theme-dark) .tok-keyword {
color: #d73a49;
font-weight: bold;
}
.cm-editor:not(.cm-theme-dark) .tok-string {
color: #032f62;
}
.cm-editor:not(.cm-theme-dark) .tok-number {
color: #005cc5;
}
.cm-editor:not(.cm-theme-dark) .tok-comment {
color: #6a737d;
font-style: italic;
}
.cm-editor:not(.cm-theme-dark) .tok-function {
color: #6f42c1;
}
.cm-editor:not(.cm-theme-dark) .tok-operator {
color: #d73a49;
}
.cm-editor:not(.cm-theme-dark) .tok-class-name {
color: #22863a;
}
.cm-editor:not(.cm-theme-dark) .tok-property {
color: #e36209;
}
.cm-editor:not(.cm-theme-dark) .tok-tag {
color: #22863a;
}
.cm-editor:not(.cm-theme-dark) .tok-attribute {
color: #6f42c1;
}
.cm-editor:not(.cm-theme-dark) .tok-variableName {
color: #e36209;
}
.cm-editor:not(.cm-theme-dark) .tok-variableName2 {
color: #005cc5;
}
.cm-editor:not(.cm-theme-dark) .tok-def {
color: #6f42c1;
}
</style>
<style scoped>
.codemirror-editor {
height: 100%;
overflow: hidden;
}
:deep(.cm-editor) {
height: 100%;
}
:deep(.cm-scroller) {
overflow: auto;
}
:deep(.cm-content) {
padding: 8px;
}
</style>