mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-28 20:02:44 +08:00
增加CodeEdiotr组件,调整MonocaEditor全局样式
This commit is contained in:
parent
9eee3d1b14
commit
a954cf0764
228
src/components/composer/common/CodeEditor.vue
Normal file
228
src/components/composer/common/CodeEditor.vue
Normal file
@ -0,0 +1,228 @@
|
|||||||
|
<template>
|
||||||
|
<div class="code-editor" :style="{ height: height }">
|
||||||
|
<div ref="editorContainer" class="editor-container"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import * as monaco from "monaco-editor";
|
||||||
|
import { toRaw } from "vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "CodeEditor",
|
||||||
|
props: {
|
||||||
|
// v-model 绑定值
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: "",
|
||||||
|
},
|
||||||
|
// 编程语言
|
||||||
|
language: {
|
||||||
|
type: String,
|
||||||
|
default: "plaintext",
|
||||||
|
},
|
||||||
|
// 编辑器高度
|
||||||
|
height: {
|
||||||
|
type: String,
|
||||||
|
default: "200px",
|
||||||
|
},
|
||||||
|
// 编辑器主题
|
||||||
|
theme: {
|
||||||
|
type: String,
|
||||||
|
default: "vs",
|
||||||
|
},
|
||||||
|
// 编辑器选项
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
emits: ["update:modelValue", "change"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editor: null,
|
||||||
|
value: null,
|
||||||
|
resizeTimeout: null,
|
||||||
|
defaultOptions: {
|
||||||
|
value: "",
|
||||||
|
// 自动布局
|
||||||
|
automaticLayout: true,
|
||||||
|
// 折叠策略
|
||||||
|
foldingStrategy: "indentation",
|
||||||
|
// 自动关闭括号
|
||||||
|
autoClosingBrackets: true,
|
||||||
|
// 制表符大小
|
||||||
|
tabSize: 2,
|
||||||
|
// 最小化
|
||||||
|
minimap: {
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
// 自动格式化
|
||||||
|
formatOnType: true,
|
||||||
|
// 自动格式化
|
||||||
|
formatOnPaste: true,
|
||||||
|
// 自动缩进
|
||||||
|
autoIndent: "full",
|
||||||
|
// 滚动超出最后一行
|
||||||
|
scrollBeyondLastLine: false,
|
||||||
|
// 字体大小
|
||||||
|
fontSize: 14,
|
||||||
|
// 行号
|
||||||
|
lineNumbers: "on",
|
||||||
|
// 行号最小字符数
|
||||||
|
lineNumbersMinChars: 3,
|
||||||
|
// 行号
|
||||||
|
renderLineNumbers: "on",
|
||||||
|
// 行装饰宽度
|
||||||
|
lineDecorationsWidth: 0,
|
||||||
|
// 圆角
|
||||||
|
roundedSelection: false,
|
||||||
|
// 行高亮
|
||||||
|
renderLineHighlight: "all",
|
||||||
|
// 仅在聚焦时高亮行
|
||||||
|
renderLineHighlightOnlyWhenFocus: true,
|
||||||
|
// 隐藏光标
|
||||||
|
hideCursorInOverviewRuler: true,
|
||||||
|
// 隐藏概览边框
|
||||||
|
overviewRulerBorder: false,
|
||||||
|
// 隐藏概览线
|
||||||
|
overviewRulerLanes: 0,
|
||||||
|
// 滚动条
|
||||||
|
scrollBars: {
|
||||||
|
vertical: "visible",
|
||||||
|
horizontal: "visible",
|
||||||
|
},
|
||||||
|
// 只读
|
||||||
|
readOnly: false,
|
||||||
|
// 光标样式
|
||||||
|
cursorStyle: "line",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// 监听 v-model 值变化
|
||||||
|
modelValue: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newValue) {
|
||||||
|
if (this.value !== newValue) {
|
||||||
|
this.value = newValue;
|
||||||
|
if (this.editor && this.editor.getValue() !== newValue) {
|
||||||
|
this.editor.setValue(newValue || "");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// 监听语言变化
|
||||||
|
language: {
|
||||||
|
immediate: true,
|
||||||
|
handler(newValue) {
|
||||||
|
if (this.editor) {
|
||||||
|
monaco.editor.setModelLanguage(this.editor.getModel(), newValue);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"$q.dark.isActive": {
|
||||||
|
immediate: true,
|
||||||
|
handler(newValue) {
|
||||||
|
monaco.editor.setTheme(newValue ? "vs-dark" : "vs");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.initEditor();
|
||||||
|
// 手动监听窗口大小变化,解决Monaco自动调整大小时导致ResizeObserver loop limit exceeded错误
|
||||||
|
window.addEventListener("resize", this.resizeEditor);
|
||||||
|
},
|
||||||
|
beforeUnmount() {
|
||||||
|
this.destroyEditor();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 初始化编辑器
|
||||||
|
initEditor() {
|
||||||
|
const options = {
|
||||||
|
...this.defaultOptions,
|
||||||
|
...this.options,
|
||||||
|
value: this.value || "",
|
||||||
|
language: this.language,
|
||||||
|
theme: this.theme,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.editor = monaco.editor.create(this.$refs.editorContainer, options);
|
||||||
|
this.listenEditorValue();
|
||||||
|
|
||||||
|
// 初始化完成后立即触发一次布局更新
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.resizeEditor();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 监听编辑器值变化
|
||||||
|
listenEditorValue() {
|
||||||
|
this.rawEditor().focus();
|
||||||
|
this.rawEditor().onDidChangeModelContent(() => {
|
||||||
|
this.value = this.getEditorValue();
|
||||||
|
this.$emit("update:modelValue", this.value);
|
||||||
|
this.$emit("change", this.value);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
// 处理窗口大小变化
|
||||||
|
resizeEditor() {
|
||||||
|
if (this.resizeTimeout) {
|
||||||
|
clearTimeout(this.resizeTimeout);
|
||||||
|
}
|
||||||
|
this.resizeTimeout = setTimeout(() => {
|
||||||
|
this.rawEditor().layout();
|
||||||
|
}, 50);
|
||||||
|
},
|
||||||
|
// 销毁编辑器
|
||||||
|
destroyEditor() {
|
||||||
|
if (this.editor) {
|
||||||
|
window.removeEventListener("resize", this.resizeEditor);
|
||||||
|
this.rawEditor().dispose();
|
||||||
|
this.editor = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取原始编辑器实例
|
||||||
|
rawEditor() {
|
||||||
|
return toRaw(this.editor);
|
||||||
|
},
|
||||||
|
// 获取编辑器实例
|
||||||
|
getEditor() {
|
||||||
|
return this.editor;
|
||||||
|
},
|
||||||
|
// 设置编辑器内容
|
||||||
|
setValue(value) {
|
||||||
|
if (this.editor) {
|
||||||
|
this.editor.setValue(value || "");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 获取编辑器内容
|
||||||
|
getValue() {
|
||||||
|
return this.editor ? this.editor.getValue() : "";
|
||||||
|
},
|
||||||
|
// 获取编辑器内容
|
||||||
|
getEditorValue() {
|
||||||
|
return this.rawEditor().getValue();
|
||||||
|
},
|
||||||
|
// 聚焦编辑器
|
||||||
|
focus() {
|
||||||
|
if (this.editor) {
|
||||||
|
this.editor.focus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.code-editor {
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
|
border-radius: 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
@ -59,16 +59,39 @@ export default {
|
|||||||
initEditor() {
|
initEditor() {
|
||||||
let monacoEditorPreferences = {
|
let monacoEditorPreferences = {
|
||||||
value: "",
|
value: "",
|
||||||
|
// 自动布局
|
||||||
automaticLayout: true,
|
automaticLayout: true,
|
||||||
|
// 折叠策略
|
||||||
foldingStrategy: "indentation",
|
foldingStrategy: "indentation",
|
||||||
|
// 自动关闭括号
|
||||||
autoClosingBrackets: true,
|
autoClosingBrackets: true,
|
||||||
|
// 制表符大小
|
||||||
tabSize: 2,
|
tabSize: 2,
|
||||||
minimap: {
|
minimap: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
|
// 自动格式化
|
||||||
formatOnType: true,
|
formatOnType: true,
|
||||||
formatOnPaste: true,
|
formatOnPaste: true,
|
||||||
|
// 自动缩进
|
||||||
autoIndent: "full",
|
autoIndent: "full",
|
||||||
|
// 行号
|
||||||
|
lineNumbersMinChars: 3,
|
||||||
|
renderLineNumbers: "on",
|
||||||
|
// 行装饰宽度
|
||||||
|
lineDecorationsWidth: 0,
|
||||||
|
// 圆角
|
||||||
|
roundedSelection: false,
|
||||||
|
// 行高亮
|
||||||
|
renderLineHighlight: "all",
|
||||||
|
// 仅在聚焦时高亮行
|
||||||
|
renderLineHighlightOnlyWhenFocus: true,
|
||||||
|
// 隐藏光标
|
||||||
|
hideCursorInOverviewRuler: true,
|
||||||
|
// 隐藏概览边框
|
||||||
|
overviewRulerBorder: false,
|
||||||
|
// 隐藏概览线
|
||||||
|
overviewRulerLanes: 0,
|
||||||
// JavaScript 特定的格式化选项
|
// JavaScript 特定的格式化选项
|
||||||
"javascript.format.insertSpaceAfterSemicolonInForStatements": true,
|
"javascript.format.insertSpaceAfterSemicolonInForStatements": true,
|
||||||
"javascript.format.insertSpaceBeforeAndAfterBinaryOperators": true,
|
"javascript.format.insertSpaceBeforeAndAfterBinaryOperators": true,
|
||||||
|
@ -13,10 +13,63 @@ body {
|
|||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.q-tooltip {
|
/* Monaco Editor 调整行号栏样式 */
|
||||||
font-size: 11px;
|
.monaco-editor .margin {
|
||||||
|
width: 40px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.monaco-editor .line-numbers {
|
||||||
|
text-align: center !important;
|
||||||
|
width: 40px !important;
|
||||||
|
padding-right: 5px !important;
|
||||||
|
left: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monaco Editor 当前行高亮样式 */
|
||||||
|
.monaco-editor .current-line {
|
||||||
|
border: none !important;
|
||||||
|
background-color: rgba(0, 0, 0, 0.03);
|
||||||
|
}
|
||||||
|
|
||||||
|
.monaco-editor .line-numbers {
|
||||||
|
color: rgba(0, 0, 0, 0.5) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body--dark .monaco-editor .line-numbers {
|
||||||
|
color: rgba(255, 255, 255, 0.5) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.monaco-editor .current-line~.line-numbers {
|
||||||
|
color: var(--q-primary) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.body--dark .monaco-editor .current-line {
|
||||||
|
background-color: rgba(255, 255, 255, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.monaco-editor .margin-view-overlays .current-line {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monaco Editor 滚动条样式 */
|
||||||
|
.monaco-editor .scrollbar {
|
||||||
|
width: 5px !important;
|
||||||
|
height: 5px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.monaco-editor .scrollbar.vertical .slider {
|
||||||
|
width: 5px !important;
|
||||||
|
border-radius: 2px !important;
|
||||||
|
background: rgba(0, 0, 0, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.monaco-editor .scrollbar.horizontal .slider {
|
||||||
|
height: 5px !important;
|
||||||
|
border-radius: 2px !important;
|
||||||
|
background: rgba(0, 0, 0, 0.2) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标签样式 */
|
||||||
.q-chip {
|
.q-chip {
|
||||||
background: #e3e3e39a;
|
background: #e3e3e39a;
|
||||||
}
|
}
|
||||||
@ -54,6 +107,10 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* 优化 Tooltip 样式 */
|
/* 优化 Tooltip 样式 */
|
||||||
|
.q-tooltip {
|
||||||
|
font-size: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
.q-tooltip {
|
.q-tooltip {
|
||||||
background: rgba(255, 255, 255, 0.18) !important;
|
background: rgba(255, 255, 255, 0.18) !important;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user