通用评估系统(四)- 前端部分计算脚本编辑组件
相关链接
说明
计算脚本编辑组件主要使用MonacoEditor
进行实现,仅做python脚本编辑器使用,不做具体的如代码提示上的优化。
安装配置
pnpm install monaco-editor
组件目录结构
部分组件代码
init.ts
/*
* @Description: 初始化monaco editor
* @Author: wang keju
* @Email: git config user.email
* @Date: 2025-02-12 21:13:52
* @LastEditTime: 2025-02-12 21:35:34
* @LastEditors: wang keju
*/
import { onMounted, onUnmounted, ref } from "vue";
import * as monaco from "monaco-editor";
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
import type { Ref } from "vue";
import type { Editor, CodeEditorProps } from "../types.d";
export function useEditor(props: CodeEditorProps, containerRef: Ref<HTMLDivElement | undefined>) {
let editorInstance: Editor | undefined = undefined;
const editor = ref<Editor>();
const code = ref<string>("");
window.MonacoEnvironment = {
getWorker(_, _label) {
return new editorWorker();
}
}
onMounted(() => {
const container = containerRef.value;
if (!container || editorInstance) return;
editorInstance = monaco.editor.create(container, {
value: props.value,
language: props.language,
readOnly: props.readonly, // 只读模式
codeLens: true, // 代码透镜
folding: true, // 代码折叠
snippetSuggestions: 'inline', // 代码提示
tabCompletion: 'on', // 代码提示按tab完成
foldingStrategy: 'auto', // 折叠策略
smoothScrolling: true, // 滚动动画
});
editorInstance.onDidChangeModelContent(() => {
// 获取编辑器内容
if (!editorInstance) return;
const value = editorInstance.getValue();
code.value = value;
});
editor.value = editorInstance;
});
onUnmounted(() => {
if (!editorInstance) return;
editorInstance.dispose();
});
return {
code,
editor
}
}
CodeEditor.vue
<!--
* @Description: 脚本编辑组件
* @Author: wang keju
* @Email: git config user.email
* @Date: 2025-02-12 07:12:25
* @LastEditTime: 2025-02-12 21:37:18
* @LastEditors: wang keju
-->
<script lang="ts" setup>
import { ref, watch, toRaw } from "vue";
import { useEditor } from "./utils/init";
import type { Editor, CodeEditorProps, CodeEditorEmits, CodeEditorExpose } from "./types.d";
const props = withDefaults(defineProps<CodeEditorProps>(), {
value: "",
language: "python",
readonly: false,
});
const emits = defineEmits<CodeEditorEmits>();
const editorRef = ref<HTMLDivElement>();
const { code, editor } = useEditor(props, editorRef);
watch(code, () => {
emits('update:value', code.value);
});
watch(props, () => {
if (!editor.value) return;
code.value = props.value;
toRaw(editor.value).setValue(props.value);
});
function getEditor(): Editor | undefined {
return toRaw(editor.value);
}
defineExpose<CodeEditorExpose>({ getEditor });
</script>
<template>
<div ref="editorRef" class="editor-wrapper"></div>
</template>
<style lang="less" scoped>
.editor-wrapper {
width: 100%;
height: 100%;
}
</style>
DiffEditor.vue
<!--
* @Description: 代码对比组件
* @Author: wang keju
* @Email: git config user.email
* @Date: 2025-02-12 07:39:00
* @LastEditTime: 2025-02-12 22:48:31
* @LastEditors: wang keju
-->
<script lang="ts" setup>
import { onMounted, ref } from "vue";
import * as monaco from "monaco-editor";
const containerRef = ref<HTMLDivElement>();
onMounted(() => {
const container = containerRef.value;
if (!container) return;
const instance = monaco.editor.createDiffEditor(container, {
theme: 'vs-dark'
})
// 给 DiffEditor 设置需要比对的代码
const originalModel = monaco.editor.createModel("123123123", "text/plain");
const modifiedModel = monaco.editor.createModel("asdasdasd", "text/plain");
instance.setModel({
original: originalModel,
modified: modifiedModel,
});
});
</script>
<template>
<div class="diff-editor-wrapper" ref="containerRef">
</div>
</template>
<style lang="less" scoped>
.diff-editor-wrapper {
height: 100%;
height: 100%;
}
</style>
初始化方法与
init.ts
中基本一致,此处代码,仅对基本使用进行说明。
说明
后续,调整显示样式,及组件代码后,具体代码见项目地址: https://gitee.com/wkjgit/assessment-instrument.git。