From 9a1e9fc4600d5a387076ebc1c8b60a0e0a35bb3a Mon Sep 17 00:00:00 2001 From: jianyi-gronk Date: Mon, 29 Jan 2024 22:21:55 +0800 Subject: [PATCH] Implementation monaco editor component --- ui-vue3/src/components/editor/MonacoEditor.ts | 63 +++++++++++ .../src/components/editor/MonacoEditor.vue | 102 ++++++++++++++++++ ui-vue3/src/main.ts | 24 +++++ 3 files changed, 189 insertions(+) create mode 100644 ui-vue3/src/components/editor/MonacoEditor.ts create mode 100644 ui-vue3/src/components/editor/MonacoEditor.vue diff --git a/ui-vue3/src/components/editor/MonacoEditor.ts b/ui-vue3/src/components/editor/MonacoEditor.ts new file mode 100644 index 000000000..bfe9478a0 --- /dev/null +++ b/ui-vue3/src/components/editor/MonacoEditor.ts @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import * as monaco from 'monaco-editor' + +export default function useMonaco(language = 'json') { + let monacoEditor: monaco.editor.IStandaloneCodeEditor | null = null + let initReadOnly = false + + const updateVal = async (val: string) => { + monacoEditor?.setValue(val) + setTimeout(async () => { + initReadOnly && monacoEditor?.updateOptions({ readOnly: false }) + await monacoEditor?.getAction('editor.action.formatDocument')?.run() + initReadOnly && monacoEditor?.updateOptions({ readOnly: true }) + }, 100) + } + + const createEditor = ( + el: HTMLElement | null, + editorOption: monaco.editor.IStandaloneEditorConstructionOptions = {} + ) => { + if (monacoEditor) { + return + } + initReadOnly = !!editorOption.readOnly + monacoEditor = + el && + monaco.editor.create(el, { + language, + minimap: { enabled: false }, + theme: 'vs-light', + multiCursorModifier: 'ctrlCmd', + tabSize: 2, + automaticLayout: true, // 自适应宽高 + ...editorOption + }) + return monacoEditor + } + const onFormatDoc = () => { + monacoEditor?.getAction('editor.action.formatDocument')?.run() + } + return { + updateVal, + getEditor: () => monacoEditor, + createEditor, + onFormatDoc + } +} diff --git a/ui-vue3/src/components/editor/MonacoEditor.vue b/ui-vue3/src/components/editor/MonacoEditor.vue new file mode 100644 index 000000000..0dfee0e15 --- /dev/null +++ b/ui-vue3/src/components/editor/MonacoEditor.vue @@ -0,0 +1,102 @@ + + + + diff --git a/ui-vue3/src/main.ts b/ui-vue3/src/main.ts index 7e2e5f887..873a41e85 100644 --- a/ui-vue3/src/main.ts +++ b/ui-vue3/src/main.ts @@ -29,6 +29,30 @@ import Vue3ColorPicker from 'vue3-colorpicker' import 'vue3-colorpicker/style.css' import 'nprogress/nprogress.css' +import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker' +import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker' +import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker' +import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker' +import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker' + +self.MonacoEnvironment = { + getWorker(_, label) { + if (label === 'json') { + return new jsonWorker() + } + if (label === 'css' || label === 'scss' || label === 'less') { + return new cssWorker() + } + if (label === 'html' || label === 'handlebars' || label === 'razor') { + return new htmlWorker() + } + if (label === 'typescript' || label === 'javascript') { + return new tsWorker() + } + return new editorWorker() + } +} + const app = createApp(App) app.use(Antd).use(Vue3ColorPicker).use(i18n).use(router).mount('#app')