134 lines
3.4 KiB
Vue
134 lines
3.4 KiB
Vue
<script lang="ts" setup>
|
|
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"
|
|
|
|
import * as monaco from "monaco-editor"
|
|
import {
|
|
nextTick,
|
|
ref,
|
|
onBeforeUnmount,
|
|
onMounted,
|
|
watch,
|
|
defineProps,
|
|
} from "vue"
|
|
|
|
const props = defineProps(["value", "language"])
|
|
|
|
const value = ref(props.value || "")
|
|
const language = ref(props.language || "C")
|
|
|
|
const monacoEditorRef = ref()
|
|
|
|
// @ts-ignore
|
|
self.MonacoEnvironment = {
|
|
getWorker(workerId: string, 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()
|
|
},
|
|
}
|
|
|
|
function reset() {
|
|
if (editor) {
|
|
editor.getModel()!.setValue(props.value || "")
|
|
}
|
|
}
|
|
|
|
onBeforeUnmount(() => {
|
|
editor && editor.dispose()
|
|
})
|
|
|
|
onMounted(() => {
|
|
editorInit()
|
|
})
|
|
|
|
watch(language, () => {
|
|
if (editor) {
|
|
monaco.editor.setModelLanguage(
|
|
editor.getModel()!,
|
|
language.value.toLowerCase()
|
|
)
|
|
}
|
|
})
|
|
|
|
let editor: monaco.editor.IStandaloneCodeEditor
|
|
|
|
function editorInit() {
|
|
nextTick(() => {
|
|
if (editor) {
|
|
editor.setValue("")
|
|
} else {
|
|
editor = monaco.editor.create(monacoEditorRef.value, {
|
|
value: value.value, // 编辑器初始显示文字
|
|
language: language.value.toLowerCase(),
|
|
automaticLayout: true, // 自适应布局
|
|
theme: "vs", // 官方自带三种主题vs, hc-black, or vs-dark
|
|
minimap: {
|
|
enabled: false,
|
|
},
|
|
fontSize: 24, // 字体大小
|
|
scrollBeyondLastLine: false, // 取消代码后面一大段空白
|
|
overviewRulerBorder: false, // 不要滚动条的边框
|
|
})
|
|
}
|
|
// 监听值的变化
|
|
editor.onDidChangeModelContent(() => {
|
|
value.value = editor.getValue()
|
|
})
|
|
})
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<el-form :inline="true">
|
|
<el-form-item label="语言" label-width="60">
|
|
<el-select class="language" v-model="language">
|
|
<el-option value="C">C</el-option>
|
|
<el-option value="Python">Python</el-option>
|
|
<el-option value="CPP">C++</el-option>
|
|
<el-option value="Java">Java</el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item>
|
|
<el-button @click="reset">重置</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
<div ref="monacoEditorRef" class="editor"></div>
|
|
<el-tabs type="border-card">
|
|
<el-tab-pane label="测试用例"> 1 </el-tab-pane>
|
|
<el-tab-pane label="执行结果"> 2 </el-tab-pane>
|
|
</el-tabs>
|
|
<el-form class="actions">
|
|
<el-form-item>
|
|
<el-button>运行</el-button>
|
|
<el-button type="primary">提交</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.language {
|
|
width: 100px;
|
|
}
|
|
|
|
.editor {
|
|
height: 500px;
|
|
}
|
|
.actions {
|
|
margin-top: 20px;
|
|
}
|
|
</style>
|