This commit is contained in:
2023-01-07 13:33:51 +08:00
parent c3746ad105
commit b9c6b404d3
6 changed files with 160 additions and 181 deletions

View File

@@ -1,25 +1,23 @@
<script lang="ts" setup>
import loader, { Monaco } from "@monaco-editor/loader"
import { ref, onBeforeUnmount, onMounted, watch, reactive } from "vue"
import { onBeforeRouteLeave, useRoute } from "vue-router"
import {
buildProblemCodeKey,
LANGUAGE,
languageLabel,
languageValue,
LANGUAGE_LABEL,
LANGUAGE_VALUE,
SOURCES,
} from "../../../utils/constants"
import storage from "../../../utils/storage"
const route = useRoute()
const { languages, template } = defineProps<{
languages: Array<LANGUAGE>
template: { [key in LANGUAGE]?: string }
const { problem } = defineProps<{
problem: {
languages: Array<LANGUAGE>
template: { [key in LANGUAGE]?: string }
}
}>()
const state = reactive({
value: "",
language: languages[0] || "C",
theme: "vs",
values: ref({ ...SOURCES }),
language: problem.languages[0] || "C",
})
const monacoEditorRef = ref()
@@ -27,78 +25,52 @@ const monacoEditorRef = ref()
let monaco: Monaco
function reset() {
state.values[state.language] =
problem.template[state.language] || SOURCES[state.language]
if (monaco && monaco.editor) {
monaco.editor.getModels()[0].setValue(template[state.language] || "")
monaco.editor.getModels()[0].setValue(state.values[state.language])
}
}
onMounted(() => {
initValue()
initEditor()
init()
})
onBeforeUnmount(() => {
monaco.editor.getModels().forEach((model) => model.dispose())
})
onBeforeRouteLeave(() => {
const key = buildProblemCodeKey(
route.params.problemID as string,
route.params.contestID as string
)
storage.set(key, {
code: state.value,
language: state.language,
theme: state.theme,
})
})
watch(
() => state.language,
() => {
if (monaco && monaco.editor) {
monaco.editor.setModelLanguage(
monaco.editor.getModels()[0],
languageValue[state.language]
LANGUAGE_VALUE[state.language]
)
reset()
}
}
)
function initValue() {
const key = buildProblemCodeKey(
route.params.problemID as string,
route.params.contestID as string
)
const problemCode = storage.get(key)
if (problemCode) {
state.value = problemCode.code
state.language = problemCode.language
state.theme = problemCode.theme
}
if (!state.value && template[state.language]) {
state.value = template[state.language] || ""
}
}
async function init() {
state.values[state.language] =
problem.template[state.language] || SOURCES[state.language]
async function initEditor() {
monaco = await loader.init()
monaco.editor.create(monacoEditorRef.value, {
value: state.value, // 编辑器初始显示文字
language: languageValue[state.language],
value: state.values[state.language], // 编辑器初始显示文字
language: LANGUAGE_VALUE[state.language],
automaticLayout: true, // 自适应布局
theme: state.theme, // 官方自带三种主题vs, hc-black, or vs-dark
theme: "vs", // 官方自带三种主题vs, hc-black, or vs-dark
minimap: {
enabled: false,
},
fontSize: 24, // 字体大小
scrollBeyondLastLine: false, // 取消代码后面一大段空白
overviewRulerBorder: false, // 不要滚动条的边框
})
// 监听值的变化
monaco.editor.getModels()[0].onDidChangeContent(() => {
console.log(1)
state.value = monaco.editor.getModels()[0].getValue()
state.values[state.language] = monaco.editor.getModels()[0].getValue()
})
}
</script>
@@ -108,10 +80,10 @@ async function initEditor() {
<el-form-item label="语言" label-width="60">
<el-select v-model="state.language" class="language">
<el-option
v-for="item in languages"
v-for="item in problem.languages"
:key="item"
:value="item"
:label="languageLabel[item]"
:label="LANGUAGE_LABEL[item]"
>
</el-option>
</el-select>
@@ -139,7 +111,7 @@ async function initEditor() {
}
.editor {
height: 500px;
height: 70%;
}
.actions {
margin-top: 16px;

View File

@@ -11,7 +11,7 @@ const contestID = route.params.contestID as string
const problemID = route.params.problemID as string
const problem = ref({
_id: 0,
_id: "",
created_by: {},
io_mode: {},
languages: [],
@@ -33,7 +33,7 @@ onMounted(() => {
<template>
<el-row v-if="problem._id">
<el-col :span="14">
<el-col :span="12">
<el-tabs type="border-card">
<el-tab-pane label="题目描述">
<ProblemContent :problem="problem" />
@@ -45,8 +45,8 @@ onMounted(() => {
<el-tab-pane label="提交情况">3</el-tab-pane>
</el-tabs>
</el-col>
<el-col :span="10">
<Editor :languages="problem.languages" :template="problem.template" />
<el-col :span="12">
<Editor :problem="problem" />
</el-col>
</el-row>
</template>