feat:对接ACS容器和虚拟机
This commit is contained in:
@@ -0,0 +1,646 @@
|
||||
<template>
|
||||
<div ref="editorContainer" class="monaco-editor-container" :style="{ height: height + 'px' }"></div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'
|
||||
import * as monaco from 'monaco-editor'
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
language: {
|
||||
type: String,
|
||||
default: 'plaintext'
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
default: 'vs-dark'
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 400
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
readOnly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['update:modelValue', 'change', 'save'])
|
||||
|
||||
const editorContainer = ref(null)
|
||||
let editor = null
|
||||
|
||||
// 默认编辑器选项
|
||||
const defaultOptions = {
|
||||
automaticLayout: true,
|
||||
fontSize: 14,
|
||||
fontFamily: 'SF Mono, Monaco, Cascadia Code, Roboto Mono, Consolas, Courier New, monospace',
|
||||
lineHeight: 1.6,
|
||||
minimap: { enabled: true },
|
||||
scrollBeyondLastLine: false,
|
||||
wordWrap: 'on',
|
||||
tabSize: 2,
|
||||
insertSpaces: true,
|
||||
detectIndentation: true,
|
||||
renderWhitespace: 'selection',
|
||||
renderLineHighlight: 'all',
|
||||
cursorBlinking: 'smooth',
|
||||
cursorSmoothCaretAnimation: true,
|
||||
smoothScrolling: true,
|
||||
mouseWheelScrollSensitivity: 1,
|
||||
fastScrollSensitivity: 5,
|
||||
scrollbar: {
|
||||
vertical: 'visible',
|
||||
horizontal: 'visible',
|
||||
useShadows: false,
|
||||
verticalHasArrows: false,
|
||||
horizontalHasArrows: false,
|
||||
verticalScrollbarSize: 10,
|
||||
horizontalScrollbarSize: 10
|
||||
},
|
||||
// 语法高亮增强配置
|
||||
semanticHighlighting: {
|
||||
enabled: true
|
||||
},
|
||||
colorDecorators: true,
|
||||
// 代码提示和补全
|
||||
suggestOnTriggerCharacters: true,
|
||||
acceptSuggestionOnEnter: 'on',
|
||||
acceptSuggestionOnCommitCharacter: true,
|
||||
quickSuggestions: {
|
||||
other: true,
|
||||
comments: false,
|
||||
strings: false
|
||||
},
|
||||
quickSuggestionsDelay: 100,
|
||||
parameterHints: {
|
||||
enabled: true,
|
||||
cycle: true
|
||||
},
|
||||
hover: {
|
||||
enabled: true,
|
||||
delay: 300
|
||||
},
|
||||
// 格式化
|
||||
formatOnPaste: true,
|
||||
formatOnType: true,
|
||||
autoIndent: 'advanced',
|
||||
// 括号配对和颜色
|
||||
bracketPairColorization: {
|
||||
enabled: true,
|
||||
independentColorPoolPerBracketType: true
|
||||
},
|
||||
guides: {
|
||||
bracketPairs: true,
|
||||
bracketPairsHorizontal: true,
|
||||
highlightActiveBracketPair: true,
|
||||
indentation: true,
|
||||
highlightActiveIndentation: true
|
||||
},
|
||||
// 代码折叠
|
||||
folding: true,
|
||||
foldingStrategy: 'auto',
|
||||
foldingHighlight: true,
|
||||
foldingImportsByDefault: false,
|
||||
showFoldingControls: 'mouseover',
|
||||
// 其他增强功能
|
||||
links: true,
|
||||
occurrencesHighlight: true,
|
||||
selectionHighlight: true,
|
||||
codeLens: true,
|
||||
lightbulb: {
|
||||
enabled: true
|
||||
},
|
||||
// 匹配括号
|
||||
matchBrackets: 'always',
|
||||
// 选择相关
|
||||
selectOnLineNumbers: true,
|
||||
selectionClipboard: false,
|
||||
// 渲染相关
|
||||
renderControlCharacters: false,
|
||||
renderFinalNewline: true,
|
||||
renderValidationDecorations: 'on'
|
||||
}
|
||||
|
||||
// 语言映射
|
||||
const getLanguageByExtension = (filename) => {
|
||||
if (!filename) return 'plaintext'
|
||||
|
||||
const ext = filename.split('.').pop()?.toLowerCase()
|
||||
|
||||
const languageMap = {
|
||||
// Web 技术
|
||||
'js': 'javascript',
|
||||
'jsx': 'javascript',
|
||||
'ts': 'typescript',
|
||||
'tsx': 'typescript',
|
||||
'html': 'html',
|
||||
'htm': 'html',
|
||||
'css': 'css',
|
||||
'scss': 'scss',
|
||||
'sass': 'sass',
|
||||
'less': 'less',
|
||||
'vue': 'html', // Vue SFC 使用 HTML 语法高亮
|
||||
'json': 'json',
|
||||
'xml': 'xml',
|
||||
|
||||
// 编程语言
|
||||
'py': 'python',
|
||||
'java': 'java',
|
||||
'c': 'c',
|
||||
'cpp': 'cpp',
|
||||
'cxx': 'cpp',
|
||||
'cc': 'cpp',
|
||||
'h': 'c',
|
||||
'hpp': 'cpp',
|
||||
'cs': 'csharp',
|
||||
'php': 'php',
|
||||
'rb': 'ruby',
|
||||
'go': 'go',
|
||||
'rs': 'rust',
|
||||
'swift': 'swift',
|
||||
'kt': 'kotlin',
|
||||
'scala': 'scala',
|
||||
'r': 'r',
|
||||
'pl': 'perl',
|
||||
'lua': 'lua',
|
||||
|
||||
// Shell 和配置
|
||||
'sh': 'shell',
|
||||
'bash': 'shell',
|
||||
'zsh': 'shell',
|
||||
'fish': 'shell',
|
||||
'ps1': 'powershell',
|
||||
'bat': 'bat',
|
||||
'cmd': 'bat',
|
||||
'dockerfile': 'dockerfile',
|
||||
'yaml': 'yaml',
|
||||
'yml': 'yaml',
|
||||
'toml': 'toml',
|
||||
'ini': 'ini',
|
||||
'conf': 'ini',
|
||||
'cfg': 'ini',
|
||||
|
||||
// 数据格式
|
||||
'sql': 'sql',
|
||||
'md': 'markdown',
|
||||
'markdown': 'markdown',
|
||||
'tex': 'latex',
|
||||
|
||||
// 其他
|
||||
'log': 'plaintext',
|
||||
'txt': 'plaintext'
|
||||
}
|
||||
|
||||
return languageMap[ext] || 'plaintext'
|
||||
}
|
||||
|
||||
// 初始化编辑器
|
||||
const initEditor = async () => {
|
||||
if (!editorContainer.value) return
|
||||
|
||||
try {
|
||||
// 设置自定义主题
|
||||
setupCustomThemes()
|
||||
|
||||
// 配置语言特性
|
||||
configureLanguageFeatures()
|
||||
|
||||
// 合并选项
|
||||
const editorOptions = {
|
||||
...defaultOptions,
|
||||
...props.options,
|
||||
value: props.modelValue,
|
||||
language: props.language,
|
||||
theme: props.theme,
|
||||
readOnly: props.readOnly
|
||||
}
|
||||
|
||||
// 创建编辑器实例
|
||||
editor = monaco.editor.create(editorContainer.value, editorOptions)
|
||||
|
||||
// 监听内容变化
|
||||
editor.onDidChangeModelContent(() => {
|
||||
const value = editor.getValue()
|
||||
emit('update:modelValue', value)
|
||||
emit('change', value)
|
||||
})
|
||||
|
||||
// 监听保存快捷键 (Ctrl+S)
|
||||
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
|
||||
emit('save')
|
||||
})
|
||||
|
||||
// 添加更多快捷键
|
||||
setupKeyboardShortcuts()
|
||||
|
||||
console.log('Monaco Editor 初始化成功')
|
||||
} catch (error) {
|
||||
console.error('Monaco Editor 初始化失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
// 配置语言特性
|
||||
const configureLanguageFeatures = () => {
|
||||
// JavaScript/TypeScript 语言配置
|
||||
monaco.languages.typescript.javascriptDefaults.setEagerModelSync(true)
|
||||
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true)
|
||||
|
||||
// 设置编译选项
|
||||
monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
|
||||
target: monaco.languages.typescript.ScriptTarget.ES2020,
|
||||
allowNonTsExtensions: true,
|
||||
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
|
||||
module: monaco.languages.typescript.ModuleKind.CommonJS,
|
||||
noEmit: true,
|
||||
esModuleInterop: true,
|
||||
jsx: monaco.languages.typescript.JsxEmit.React,
|
||||
reactNamespace: 'React',
|
||||
allowJs: true,
|
||||
typeRoots: ['node_modules/@types']
|
||||
})
|
||||
|
||||
// CSS 语言配置
|
||||
monaco.languages.css.cssDefaults.setOptions({
|
||||
validate: true,
|
||||
lint: {
|
||||
compatibleVendorPrefixes: 'ignore',
|
||||
vendorPrefix: 'warning',
|
||||
duplicateProperties: 'warning',
|
||||
emptyRules: 'warning',
|
||||
importStatement: 'ignore',
|
||||
boxModel: 'ignore',
|
||||
universalSelector: 'ignore',
|
||||
zeroUnits: 'ignore',
|
||||
fontFaceProperties: 'warning',
|
||||
hexColorLength: 'error',
|
||||
argumentsInColorFunction: 'error',
|
||||
unknownProperties: 'warning',
|
||||
ieHack: 'ignore',
|
||||
unknownVendorSpecificProperties: 'ignore',
|
||||
propertyIgnoredDueToDisplay: 'warning',
|
||||
important: 'ignore',
|
||||
float: 'ignore',
|
||||
idSelector: 'ignore'
|
||||
}
|
||||
})
|
||||
|
||||
// HTML 语言配置
|
||||
monaco.languages.html.htmlDefaults.setOptions({
|
||||
format: {
|
||||
tabSize: 2,
|
||||
insertSpaces: true,
|
||||
wrapLineLength: 120,
|
||||
unformatted: 'default"',
|
||||
contentUnformatted: 'pre,code,textarea',
|
||||
indentInnerHtml: false,
|
||||
preserveNewLines: true,
|
||||
maxPreserveNewLines: undefined,
|
||||
indentHandlebars: false,
|
||||
endWithNewline: false,
|
||||
extraLiners: 'head, body, /html',
|
||||
wrapAttributes: 'auto'
|
||||
},
|
||||
suggest: {},
|
||||
validate: true
|
||||
})
|
||||
|
||||
// JSON 语言配置
|
||||
monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
|
||||
validate: true,
|
||||
allowComments: false,
|
||||
schemas: [],
|
||||
enableSchemaRequest: true
|
||||
})
|
||||
}
|
||||
|
||||
// 设置键盘快捷键
|
||||
const setupKeyboardShortcuts = () => {
|
||||
if (!editor) return
|
||||
|
||||
// 格式化代码 (Shift+Alt+F)
|
||||
editor.addCommand(monaco.KeyMod.Shift | monaco.KeyMod.Alt | monaco.KeyCode.KeyF, () => {
|
||||
editor.getAction('editor.action.formatDocument').run()
|
||||
})
|
||||
|
||||
// 查找 (Ctrl+F)
|
||||
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyF, () => {
|
||||
editor.getAction('actions.find').run()
|
||||
})
|
||||
|
||||
// 替换 (Ctrl+H)
|
||||
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyH, () => {
|
||||
editor.getAction('editor.action.startFindReplaceAction').run()
|
||||
})
|
||||
|
||||
// 转到行 (Ctrl+G)
|
||||
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyG, () => {
|
||||
editor.getAction('editor.action.gotoLine').run()
|
||||
})
|
||||
|
||||
// 注释/取消注释 (Ctrl+/)
|
||||
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Slash, () => {
|
||||
editor.getAction('editor.action.commentLine').run()
|
||||
})
|
||||
}
|
||||
|
||||
// 设置自定义主题
|
||||
const setupCustomThemes = () => {
|
||||
// 定义自定义深色主题 - 增强版
|
||||
monaco.editor.defineTheme('custom-dark', {
|
||||
base: 'vs-dark',
|
||||
inherit: true,
|
||||
rules: [
|
||||
// 注释
|
||||
{ token: 'comment', foreground: '6A9955', fontStyle: 'italic' },
|
||||
{ token: 'comment.line', foreground: '6A9955', fontStyle: 'italic' },
|
||||
{ token: 'comment.block', foreground: '6A9955', fontStyle: 'italic' },
|
||||
|
||||
// 关键字
|
||||
{ token: 'keyword', foreground: '569CD6', fontStyle: 'bold' },
|
||||
{ token: 'keyword.control', foreground: 'C586C0', fontStyle: 'bold' },
|
||||
{ token: 'keyword.operator', foreground: '569CD6' },
|
||||
{ token: 'keyword.other', foreground: '569CD6' },
|
||||
|
||||
// 字符串
|
||||
{ token: 'string', foreground: 'CE9178' },
|
||||
{ token: 'string.quoted', foreground: 'CE9178' },
|
||||
{ token: 'string.template', foreground: 'CE9178' },
|
||||
{ token: 'string.regexp', foreground: 'D16969' },
|
||||
|
||||
// 数字
|
||||
{ token: 'number', foreground: 'B5CEA8' },
|
||||
{ token: 'number.hex', foreground: 'B5CEA8' },
|
||||
{ token: 'number.octal', foreground: 'B5CEA8' },
|
||||
{ token: 'number.binary', foreground: 'B5CEA8' },
|
||||
|
||||
// 变量和标识符
|
||||
{ token: 'variable', foreground: '9CDCFE' },
|
||||
{ token: 'variable.name', foreground: '9CDCFE' },
|
||||
{ token: 'variable.parameter', foreground: '9CDCFE' },
|
||||
{ token: 'variable.other', foreground: '9CDCFE' },
|
||||
|
||||
// 函数和方法
|
||||
{ token: 'function', foreground: 'DCDCAA' },
|
||||
{ token: 'function.name', foreground: 'DCDCAA' },
|
||||
{ token: 'method', foreground: 'DCDCAA' },
|
||||
{ token: 'method.name', foreground: 'DCDCAA' },
|
||||
|
||||
// 类型和类
|
||||
{ token: 'type', foreground: '4EC9B0' },
|
||||
{ token: 'type.name', foreground: '4EC9B0' },
|
||||
{ token: 'class', foreground: '4EC9B0' },
|
||||
{ token: 'class.name', foreground: '4EC9B0' },
|
||||
{ token: 'interface', foreground: 'B8D7A3' },
|
||||
{ token: 'enum', foreground: 'B8D7A3' },
|
||||
{ token: 'struct', foreground: '86C691' },
|
||||
|
||||
// 操作符和标点
|
||||
{ token: 'operator', foreground: 'D4D4D4' },
|
||||
{ token: 'delimiter', foreground: 'D4D4D4' },
|
||||
{ token: 'punctuation', foreground: 'D4D4D4' },
|
||||
|
||||
// 特殊标记
|
||||
{ token: 'tag', foreground: '569CD6' },
|
||||
{ token: 'tag.name', foreground: '569CD6' },
|
||||
{ token: 'attribute', foreground: '9CDCFE' },
|
||||
{ token: 'attribute.name', foreground: '9CDCFE' },
|
||||
{ token: 'attribute.value', foreground: 'CE9178' },
|
||||
|
||||
// 装饰器和宏
|
||||
{ token: 'decorator', foreground: 'C586C0' },
|
||||
{ token: 'macro', foreground: 'C586C0' },
|
||||
|
||||
// JavaScript/TypeScript 特定
|
||||
{ token: 'support.type', foreground: '4EC9B0' },
|
||||
{ token: 'support.class', foreground: '4EC9B0' },
|
||||
{ token: 'support.function', foreground: 'DCDCAA' },
|
||||
{ token: 'support.variable', foreground: '4FC1FF' },
|
||||
|
||||
// CSS 特定
|
||||
{ token: 'property', foreground: '9CDCFE' },
|
||||
{ token: 'property.name', foreground: '9CDCFE' },
|
||||
{ token: 'property.value', foreground: 'CE9178' },
|
||||
{ token: 'selector', foreground: 'D7BA7D' },
|
||||
|
||||
// JSON 特定
|
||||
{ token: 'key', foreground: '9CDCFE' },
|
||||
{ token: 'value', foreground: 'CE9178' }
|
||||
],
|
||||
colors: {
|
||||
'editor.background': '#1E1E1E',
|
||||
'editor.foreground': '#D4D4D4',
|
||||
'editorLineNumber.foreground': '#858585',
|
||||
'editorLineNumber.activeForeground': '#C6C6C6',
|
||||
'editor.selectionBackground': '#264F78',
|
||||
'editor.inactiveSelectionBackground': '#3A3D41',
|
||||
'editorCursor.foreground': '#AEAFAD',
|
||||
'editor.findMatchBackground': '#515C6A',
|
||||
'editor.findMatchHighlightBackground': '#EA5C0055',
|
||||
'editor.linkedEditingBackground': '#FF00007A',
|
||||
'editorBracketMatch.background': '#0064001A',
|
||||
'editorBracketMatch.border': '#888888'
|
||||
}
|
||||
})
|
||||
|
||||
// 定义自定义浅色主题 - 增强版
|
||||
monaco.editor.defineTheme('custom-light', {
|
||||
base: 'vs',
|
||||
inherit: true,
|
||||
rules: [
|
||||
// 注释
|
||||
{ token: 'comment', foreground: '008000', fontStyle: 'italic' },
|
||||
{ token: 'comment.line', foreground: '008000', fontStyle: 'italic' },
|
||||
{ token: 'comment.block', foreground: '008000', fontStyle: 'italic' },
|
||||
|
||||
// 关键字
|
||||
{ token: 'keyword', foreground: '0000FF', fontStyle: 'bold' },
|
||||
{ token: 'keyword.control', foreground: 'AF00DB', fontStyle: 'bold' },
|
||||
{ token: 'keyword.operator', foreground: '0000FF' },
|
||||
{ token: 'keyword.other', foreground: '0000FF' },
|
||||
|
||||
// 字符串
|
||||
{ token: 'string', foreground: 'A31515' },
|
||||
{ token: 'string.quoted', foreground: 'A31515' },
|
||||
{ token: 'string.template', foreground: 'A31515' },
|
||||
{ token: 'string.regexp', foreground: 'D16969' },
|
||||
|
||||
// 数字
|
||||
{ token: 'number', foreground: '098658' },
|
||||
{ token: 'number.hex', foreground: '098658' },
|
||||
{ token: 'number.octal', foreground: '098658' },
|
||||
{ token: 'number.binary', foreground: '098658' },
|
||||
|
||||
// 变量和标识符
|
||||
{ token: 'variable', foreground: '001080' },
|
||||
{ token: 'variable.name', foreground: '001080' },
|
||||
{ token: 'variable.parameter', foreground: '001080' },
|
||||
{ token: 'variable.other', foreground: '001080' },
|
||||
|
||||
// 函数和方法
|
||||
{ token: 'function', foreground: '795E26' },
|
||||
{ token: 'function.name', foreground: '795E26' },
|
||||
{ token: 'method', foreground: '795E26' },
|
||||
{ token: 'method.name', foreground: '795E26' },
|
||||
|
||||
// 类型和类
|
||||
{ token: 'type', foreground: '267F99' },
|
||||
{ token: 'type.name', foreground: '267F99' },
|
||||
{ token: 'class', foreground: '267F99' },
|
||||
{ token: 'class.name', foreground: '267F99' },
|
||||
{ token: 'interface', foreground: '007ACC' },
|
||||
{ token: 'enum', foreground: '007ACC' },
|
||||
{ token: 'struct', foreground: '267F99' },
|
||||
|
||||
// 操作符和标点
|
||||
{ token: 'operator', foreground: '000000' },
|
||||
{ token: 'delimiter', foreground: '000000' },
|
||||
{ token: 'punctuation', foreground: '000000' },
|
||||
|
||||
// 特殊标记
|
||||
{ token: 'tag', foreground: '800000' },
|
||||
{ token: 'tag.name', foreground: '800000' },
|
||||
{ token: 'attribute', foreground: 'FF0000' },
|
||||
{ token: 'attribute.name', foreground: 'FF0000' },
|
||||
{ token: 'attribute.value', foreground: '0000FF' },
|
||||
|
||||
// 装饰器和宏
|
||||
{ token: 'decorator', foreground: 'AF00DB' },
|
||||
{ token: 'macro', foreground: 'AF00DB' },
|
||||
|
||||
// JavaScript/TypeScript 特定
|
||||
{ token: 'support.type', foreground: '267F99' },
|
||||
{ token: 'support.class', foreground: '267F99' },
|
||||
{ token: 'support.function', foreground: '795E26' },
|
||||
{ token: 'support.variable', foreground: '0070C1' },
|
||||
|
||||
// CSS 特定
|
||||
{ token: 'property', foreground: 'FF0000' },
|
||||
{ token: 'property.name', foreground: 'FF0000' },
|
||||
{ token: 'property.value', foreground: '0451A5' },
|
||||
{ token: 'selector', foreground: '800000' },
|
||||
|
||||
// JSON 特定
|
||||
{ token: 'key', foreground: '0451A5' },
|
||||
{ token: 'value', foreground: 'A31515' }
|
||||
],
|
||||
colors: {
|
||||
'editor.background': '#FFFFFF',
|
||||
'editor.foreground': '#000000',
|
||||
'editorLineNumber.foreground': '#237893',
|
||||
'editor.selectionBackground': '#ADD6FF',
|
||||
'editor.inactiveSelectionBackground': '#E5EBF1',
|
||||
'editorCursor.foreground': '#000000',
|
||||
'editor.findMatchBackground': '#A8AC94',
|
||||
'editor.findMatchHighlightBackground': '#EA5C0055'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 更新编辑器值
|
||||
const updateValue = (newValue) => {
|
||||
if (editor && editor.getValue() !== newValue) {
|
||||
editor.setValue(newValue || '')
|
||||
}
|
||||
}
|
||||
|
||||
// 更新编辑器语言
|
||||
const updateLanguage = (newLanguage) => {
|
||||
if (editor) {
|
||||
const model = editor.getModel()
|
||||
if (model) {
|
||||
monaco.editor.setModelLanguage(model, newLanguage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 更新编辑器主题
|
||||
const updateTheme = (newTheme) => {
|
||||
if (editor) {
|
||||
monaco.editor.setTheme(newTheme)
|
||||
}
|
||||
}
|
||||
|
||||
// 调整编辑器大小
|
||||
const resizeEditor = () => {
|
||||
if (editor) {
|
||||
nextTick(() => {
|
||||
editor.layout()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 获取编辑器实例
|
||||
const getEditor = () => editor
|
||||
|
||||
// 聚焦编辑器
|
||||
const focus = () => {
|
||||
if (editor) {
|
||||
editor.focus()
|
||||
}
|
||||
}
|
||||
|
||||
// 设置编辑器内容
|
||||
const setValue = (value) => {
|
||||
if (editor) {
|
||||
editor.setValue(value || '')
|
||||
}
|
||||
}
|
||||
|
||||
// 获取编辑器内容
|
||||
const getValue = () => {
|
||||
return editor ? editor.getValue() : ''
|
||||
}
|
||||
|
||||
// 监听属性变化
|
||||
watch(() => props.modelValue, updateValue)
|
||||
watch(() => props.language, updateLanguage)
|
||||
watch(() => props.theme, updateTheme)
|
||||
watch(() => props.height, resizeEditor)
|
||||
|
||||
// 生命周期
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
initEditor()
|
||||
})
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (editor) {
|
||||
editor.dispose()
|
||||
editor = null
|
||||
}
|
||||
})
|
||||
|
||||
// 暴露方法给父组件
|
||||
defineExpose({
|
||||
getEditor,
|
||||
focus,
|
||||
setValue,
|
||||
getValue,
|
||||
resizeEditor,
|
||||
getLanguageByExtension
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.monaco-editor-container {
|
||||
width: 100%;
|
||||
border: 1px solid #e4e7ed;
|
||||
border-radius: 4px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.monaco-editor-container:focus-within {
|
||||
border-color: #409eff;
|
||||
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user