基于 Vue 3 和 CodeMirror 的代码编辑器

93 阅读2分钟

功能概述

这是一个基于 Vue 3 和 CodeMirror 的代码编辑器组件,主要功能包括:

 支持代码编辑

 提供语法高亮和自动补全功能

 可运行代码并显示执行结果

编辑器功能

 使用 CodeMirror 6 作为编辑器核心

 支持语法高亮

 启用自动补全功能(输入时自动触发)

 显示行号

使用方法

<template>
  <div>
    <el-select v-model="language" placeholder="Python">
      <el-option label="Python" value="python" />
      <el-option label="javascript " value="javascript" />
    </el-select>
    <div ref="editorContainer" class="code-editor"></div>
    <button @click="callBackendApi">运行</button>
    <div class="result-area">
      <h3>运行结果</h3>
      <pre>{{ apiResponse }}</pre>
    </div>
  </div>
</template>
import { ref, onMounted, onBeforeUnmount, watch } from "vue";
import { EditorState } from "@codemirror/state";
import { EditorView, lineNumbers } from "@codemirror/view";
import { python } from "@codemirror/lang-python";
import { javascript } from "@codemirror/lang-javascript";
import { autocompletion } from "@codemirror/autocomplete";
import { syntaxHighlighting, defaultHighlightStyle } from "@codemirror/language";
import axios from "axios";
import { useRoute } from "vue-router";
const editorContainer = ref<HTMLElement | null>(null);
const language = ref("python");
const code = ref("");
const apiResponse = ref("");
const route = useRoute();
// 定义 Python 默认示例代码
const defaultCode = {
  python: `def hello():
    return "Hello, Python!"
print(hello())`,
  javascript: `function hello() {
    return "Hello, JavaScript!";
  }
  console.log(hello());  
  hello();  `
};
// 获取语言扩展配置
const getLanguageExtension = () => {
  switch (language.value) {
    case "python":
      return python();
    case "javascript":
      return javascript();
    default:
      return python();
  }
};
// 初始化编辑器
const initEditor = () => {
  code.value = defaultCode[language.value];
  const state = EditorState.create({
    doc: code.value,
    extensions: [
      lineNumbers(),
      getLanguageExtension(),
      autocompletion({ activateOnTyping: true }),
      syntaxHighlighting(defaultHighlightStyle, { fallback: true }),
      EditorView.lineWrapping
    ]
  });
  if (editorContainer.value) {
    editorView = new EditorView({
      state,
      parent: editorContainer.value,
      dispatch: (update) => {
        editorView?.update([update]);
        if (update.docChanged) {
          code.value = update.state.doc.toString();
        }
      }
    });
  }
};
let editorView: EditorView | null = null;
watch(language, (newVal) => {
  if (editorView) {
    editorView.destroy();
    initEditor();
  }
});
onMounted(async () => {
  initEditor();
});
onBeforeUnmount(() => {
  editorView?.destroy();
});
const callBackendApi = () => {
  try {
    // 使用 eval 执行 JavaScript 代码
    if (language.value === "javascript") {
      const result = eval(code.value);
      apiResponse.value = result !== undefined ? String(result) : "代码已执行,无返回值";
    } else {
      apiResponse.value = "当前只支持 JavaScript 代码执行";
    }
  } catch (error) {
    apiResponse.value = `执行错误: ${error}`;
  }
};

依赖项

 Vue 3

 CodeMirror 6 及相关扩展:

 @codemirror/state

 @codemirror/view

 @codemirror/lang-python

 @codemirror/lang-javascript

 @codemirror/autocomplete

 @codemirror/language

注意事项

 目前仅支持 Python和javascript 语言,可以通过CodeMirror相关依赖支持不同语言

 此组件需要与后端进行配合使用,需要用到python环境将python代码通过接口传输给后端执行使用,javaScript不需要,可以直接在线运行

 后端 API 调用功能尚未实现(需要补充 callBackendApi 方法)

Snipaste_2025-09-22_14-47-46.png