Skip to content

Commit

Permalink
Merge pull request apache#186 from jianyi-gronk/feature/ui/monacoEdit…
Browse files Browse the repository at this point in the history
…orComponent

improve monaco-editor component
  • Loading branch information
chickenlj authored Jan 30, 2024
2 parents 9e686b4 + 63518f4 commit 41ab9a0
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 27 deletions.
63 changes: 63 additions & 0 deletions ui-vue3/src/components/editor/MonacoEditor.ts
Original file line number Diff line number Diff line change
@@ -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
}
}
102 changes: 102 additions & 0 deletions ui-vue3/src/components/editor/MonacoEditor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<!--
~ 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.
-->
<template>
<div
:id="editorId"
:style="{
width: typeof width === 'number' ? width + 'px' : width,
height: typeof height === 'number' ? height + 'px' : height
}"
></div>
</template>

<script lang="ts" setup>
import { defineEmits, onMounted, watch } from 'vue'
import useMonaco from './MonacoEditor'
const emit = defineEmits(['update:modelValue', 'blur'])
const props = defineProps({
modelValue: {
type: String,
default: ''
},
width: {
type: [String, Number],
default: '100%'
},
height: {
type: [String, Number],
default: '100%'
},
theme: {
type: String,
default: 'vs-light'
},
language: {
type: String,
default: 'json'
},
editorId: {
type: String,
default: 'editor'
},
editorOptions: {
type: Object,
default: () => ({})
},
readonly: {
type: Boolean,
default: false
}
})
const { createEditor, updateVal, getEditor, onFormatDoc } = useMonaco(props.language)
const updateMonacoVal = (_val?: string) => {
const val = _val || props.modelValue
updateVal(val)
}
watch(
() => props.modelValue,
(val) => {
val !== getEditor()?.getValue() && updateMonacoVal(val)
}
)
onMounted(() => {
const editor = createEditor(document.querySelector(`#${props.editorId}`), {
theme: props.theme,
readOnly: props.readonly,
...props.editorOptions
})
updateMonacoVal()
if (editor) {
editor.onDidChangeModelContent(() => {
emit('update:modelValue', editor.getValue())
})
editor.onDidBlurEditorText(() => {
emit('blur')
})
}
})
defineExpose({
onFormatDoc
})
</script>
32 changes: 5 additions & 27 deletions ui-vue3/src/views/resources/services/tabs/debug.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@
<a-tree block-node :tree-data="outputParamType" class="description-item-content" />
</a-descriptions-item>
<a-descriptions-item label="请求" :span="2">
<div ref="requestEditor" class="editor"></div>
<monaco-editor editorId="requestEditor" width="90%" height="300px" />
</a-descriptions-item>
<a-descriptions-item label="响应" :span="2">
<div ref="responseEditor" class="editor"></div>
<monaco-editor editorId="responseEditor" width="90%" height="300px" />
</a-descriptions-item>
</a-descriptions>
<a-button type="primary">发送请求</a-button>
Expand All @@ -61,8 +61,8 @@
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue'
import * as monaco from 'monaco-editor'
import { ref, reactive } from 'vue'
import MonacoEditor from '@/components/editor/MonacoEditor.vue';
const methodTabs = reactive([
'login',
Expand Down Expand Up @@ -141,26 +141,8 @@ const outputParamType = [
]
}
]
const requestEditor = ref(null)
const responseEditor = ref(null)
const createEditor = (element: HTMLElement) => {
monaco.editor.create(element, {
value: '',
language: 'json',
theme: 'vs-dark',
automaticLayout: true,
fontSize: 14,
lineNumbers: 'off',
roundedSelection: true
})
}
onMounted(() => {
createEditor(requestEditor.value![0])
createEditor(responseEditor.value![0])
})
</script>

<style lang="less" scoped>
.__container_services_tabs_debug {
width: 100%;
Expand All @@ -172,9 +154,5 @@ onMounted(() => {
margin-left: 20px;
width: 90%;
}
.editor {
width: 90%;
height: 300px;
}
}
</style>

0 comments on commit 41ab9a0

Please sign in to comment.