mirror of
https://gitee.com/dromara/go-view.git
synced 2026-04-23 00:00:12 +08:00
fix: 解决编辑器的问题
This commit is contained in:
@@ -1,46 +1,83 @@
|
||||
import { ref, onBeforeUnmount, nextTick } from 'vue'
|
||||
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js'
|
||||
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'
|
||||
|
||||
export const useMonacoEditor = (language = 'json') => {
|
||||
export const useMonacoEditor = (language = 'javascript') => {
|
||||
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 el = ref<HTMLElement | null>(null)
|
||||
|
||||
// @ts-ignore
|
||||
self.MonacoEnvironment = {
|
||||
getWorker(_: any, label: string) {
|
||||
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 createEditor = (
|
||||
el: HTMLElement | null,
|
||||
editorOption: monaco.editor.IStandaloneEditorConstructionOptions = {}
|
||||
) => {
|
||||
if (monacoEditor) {
|
||||
return
|
||||
}
|
||||
// 格式化
|
||||
const onFormatDoc = async () => {
|
||||
await monacoEditor?.getAction('monacoEditor.action.formatDocument')?.run()
|
||||
}
|
||||
|
||||
// 更新
|
||||
const updateVal = (val: string) => {
|
||||
nextTick(async () => {
|
||||
monacoEditor?.setValue(val)
|
||||
initReadOnly && monacoEditor?.updateOptions({ readOnly: false })
|
||||
await onFormatDoc()
|
||||
initReadOnly && monacoEditor?.updateOptions({ readOnly: true })
|
||||
})
|
||||
}
|
||||
|
||||
// 创建实例
|
||||
const createEditor = (editorOption: monaco.editor.IStandaloneEditorConstructionOptions = {}) => {
|
||||
if (!el.value) return
|
||||
const javascriptModel = monaco.editor.createModel('', language)
|
||||
initReadOnly = !!editorOption.readOnly
|
||||
monacoEditor =
|
||||
el &&
|
||||
monaco.editor.create(el, {
|
||||
language,
|
||||
minimap: { enabled: false },
|
||||
theme: 'vs-dark',
|
||||
multiCursorModifier: 'ctrlCmd',
|
||||
scrollbar: {
|
||||
verticalScrollbarSize: 8,
|
||||
horizontalScrollbarSize: 8
|
||||
},
|
||||
tabSize: 2,
|
||||
automaticLayout: true, // 自适应宽高
|
||||
...editorOption
|
||||
})
|
||||
// 创建
|
||||
monacoEditor = monaco.editor.create(el.value, {
|
||||
model: javascriptModel,
|
||||
minimap: { enabled: true },
|
||||
roundedSelection: false,
|
||||
theme: 'vs-dark',
|
||||
multiCursorModifier: 'ctrlCmd',
|
||||
scrollbar: {
|
||||
verticalScrollbarSize: 8,
|
||||
horizontalScrollbarSize: 8
|
||||
},
|
||||
tabSize: 2,
|
||||
fontSize: 16, //字体大小
|
||||
autoIndent: 'advanced', //自动布局
|
||||
automaticLayout: true, // 自适应宽高
|
||||
...editorOption
|
||||
})
|
||||
|
||||
return monacoEditor
|
||||
}
|
||||
const onFormatDoc = () => {
|
||||
monacoEditor?.getAction('editor.action.formatDocument').run()
|
||||
}
|
||||
|
||||
// 卸载
|
||||
onBeforeUnmount(() => {
|
||||
if (monacoEditor) monacoEditor.dispose()
|
||||
})
|
||||
|
||||
return {
|
||||
el,
|
||||
updateVal,
|
||||
getEditor: () => monacoEditor,
|
||||
createEditor,
|
||||
|
||||
@@ -1,75 +1,65 @@
|
||||
<template>
|
||||
<div class="editor-area" :style="{ width, height }">
|
||||
</div>
|
||||
<div ref="el" class="editor-area" :style="{ width, height }"></div>
|
||||
</template>
|
||||
|
||||
<script lang='ts'>
|
||||
import { defineComponent, ref } from 'vue'
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, watch, PropType } from 'vue'
|
||||
import { useMonacoEditor } from './index.hook'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '90vh'
|
||||
},
|
||||
language: {
|
||||
type: String,
|
||||
default: 'json'
|
||||
},
|
||||
preComment: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
modelValue: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
editorOptions: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
const props = defineProps({
|
||||
width: {
|
||||
type: String as PropType<string>,
|
||||
default: '100%'
|
||||
},
|
||||
watch: {
|
||||
modelValue(val) {
|
||||
val !== this.getEditor()?.getValue() && this.updateMonacoVal(val)
|
||||
}
|
||||
height: {
|
||||
type: String as PropType<string>,
|
||||
default: '90vh'
|
||||
},
|
||||
setup(props) {
|
||||
const { updateVal, getEditor, createEditor, onFormatDoc } = useMonacoEditor(props.language)
|
||||
const isFull = ref(false)
|
||||
return {
|
||||
isFull,
|
||||
updateVal,
|
||||
getEditor,
|
||||
createEditor,
|
||||
onFormatDoc
|
||||
}
|
||||
language: {
|
||||
type: String as PropType<string>,
|
||||
default: 'javascript'
|
||||
},
|
||||
methods: {
|
||||
updateMonacoVal(_val?: string) {
|
||||
const { modelValue, preComment } = this.$props
|
||||
const val = preComment ? `${preComment}\n${_val || modelValue}` : (_val || modelValue)
|
||||
this.updateVal(val)
|
||||
}
|
||||
preComment: {
|
||||
type: String as PropType<string>,
|
||||
default: ''
|
||||
},
|
||||
mounted() {
|
||||
if (this.$el) {
|
||||
const monacoEditor = this.createEditor(this.$el, this.$props.editorOptions)
|
||||
this.updateMonacoVal()
|
||||
monacoEditor!.onDidChangeModelContent(() => {
|
||||
this.$emit('update:modelValue', monacoEditor!.getValue())
|
||||
})
|
||||
monacoEditor!.onDidBlurEditorText(() => {
|
||||
this.$emit('blur')
|
||||
})
|
||||
}
|
||||
modelValue: {
|
||||
type: String as PropType<string>,
|
||||
default: ''
|
||||
},
|
||||
editorOptions: {
|
||||
type: Object as PropType<object>,
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const emits = defineEmits(['blur', 'update:modelValue'])
|
||||
|
||||
const { el, updateVal, getEditor, createEditor } = useMonacoEditor(props.language)
|
||||
|
||||
const updateMonacoVal = (_val?: string) => {
|
||||
const { modelValue, preComment } = props
|
||||
const val = preComment ? `${preComment}\n${_val || modelValue}` : _val || modelValue
|
||||
updateVal(val)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const monacoEditor = createEditor(props.editorOptions)
|
||||
monacoEditor!.onDidChangeModelContent(() => {
|
||||
emits('update:modelValue', monacoEditor!.getValue())
|
||||
})
|
||||
monacoEditor!.onDidBlurEditorText(() => {
|
||||
emits('blur')
|
||||
})
|
||||
updateMonacoVal()
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(val: string) => {
|
||||
val !== getEditor()?.getValue() && updateMonacoVal(val)
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -81,4 +71,4 @@ export default defineComponent({
|
||||
padding-left: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user