Skip to content

代码编辑器示例

使用 Monaco Editor(VS Code 同款编辑器)实现代码编辑功能。

功能特性

  • 📝 代码高亮 - 支持多种编程语言
  • 🎨 主题切换 - 支持亮色/暗色主题
  • 🔍 代码提示 - 智能代码补全
  • 📐 代码格式化 - 自动格式化代码

安装依赖

bash
npm install monaco-editor vite-plugin-monaco-editor

基础用法

vue
<template>
  <div ref="editorContainer" class="editor-container"></div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as monaco from 'monaco-editor'

const editorContainer = ref()
let editor = null

onMounted(() => {
  // 创建编辑器
  editor = monaco.editor.create(editorContainer.value, {
    value: '// 请输入代码',
    language: 'javascript',
    theme: 'vs-dark',
    automaticLayout: true
  })
})

onUnmounted(() => {
  editor?.dispose()
})
</script>

<style scoped>
.editor-container {
  width: 100%;
  height: 500px;
}
</style>

完整示例

vue
<template>
  <div class="page-container">
    <div class="toolbar">
      <h2 class="page-title">代码编辑器示例</h2>
      <div class="actions">
        <el-select v-model="language" @change="changeLanguage" style="width: 120px; margin-right: 10px;">
          <el-option label="JavaScript" value="javascript" />
          <el-option label="TypeScript" value="typescript" />
          <el-option label="HTML" value="html" />
          <el-option label="CSS" value="css" />
          <el-option label="JSON" value="json" />
          <el-option label="SQL" value="sql" />
        </el-select>
        
        <el-select v-model="theme" @change="changeTheme" style="width: 120px; margin-right: 10px;">
          <el-option label="Dark" value="vs-dark" />
          <el-option label="Light" value="vs" />
          <el-option label="High Contrast" value="hc-black" />
        </el-select>
        
        <el-button @click="getValue">获取内容</el-button>
        <el-button @click="setValue">设置内容</el-button>
        <el-button @click="formatCode">格式化</el-button>
      </div>
    </div>
    
    <div ref="editorContainer" class="editor-container"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import * as monaco from 'monaco-editor'
import { ElMessage } from 'element-plus'

const editorContainer = ref()
let editor = null

const language = ref('javascript')
const theme = ref('vs-dark')

const defaultCode = `// 欢迎使用 Monaco Editor
function hello() {
  console.log('Hello, World!');
}

// 调用函数
hello();`

onMounted(() => {
  editor = monaco.editor.create(editorContainer.value, {
    value: defaultCode,
    language: language.value,
    theme: theme.value,
    automaticLayout: true,
    minimap: { enabled: true },
    fontSize: 14,
    lineNumbers: 'on',
    roundedSelection: false,
    scrollBeyondLastLine: false,
    readOnly: false
  })
})

onUnmounted(() => {
  editor?.dispose()
})

const changeLanguage = () => {
  monaco.editor.setModelLanguage(editor.getModel(), language.value)
}

const changeTheme = () => {
  monaco.editor.setTheme(theme.value)
}

const getValue = () => {
  const value = editor.getValue()
  ElMessage.success('代码已打印到控制台')
  console.log(value)
}

const setValue = () => {
  const newCode = `// 新设置的代码\nconst greeting = 'Hello';\nconsole.log(greeting);`
  editor.setValue(newCode)
  ElMessage.success('代码已设置')
}

const formatCode = () => {
  editor.getAction('editor.action.formatDocument').run()
  ElMessage.success('代码已格式化')
}
</script>

<style scoped>
.page-container {
  padding: 20px;
  height: calc(100vh - 60px);
  display: flex;
  flex-direction: column;
}

.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.editor-container {
  flex: 1;
  border: 1px solid #ccc;
}
</style>

配置选项

javascript
const editorOptions = {
  // 语言
  language: 'javascript',
  
  // 主题
  theme: 'vs-dark',
  
  // 字体大小
  fontSize: 14,
  
  // 最小地图
  minimap: { enabled: true },
  
  // 行号
  lineNumbers: 'on', // 'on' | 'off' | 'relative' | 'interval'
  
  // 自动布局
  automaticLayout: true,
  
  // 只读
  readOnly: false,
  
  // 自动换行
  wordWrap: 'on',
  
  // 光标样式
  cursorStyle: 'line',
  
  // 制表符大小
  tabSize: 2,
  
  // 插入空格代替制表符
  insertSpaces: true,
  
  // 折叠
  folding: true,
  
  // 渲染空白字符
  renderWhitespace: 'selection'
}

常用 API

javascript
// 获取编辑器内容
const value = editor.getValue()

// 设置编辑器内容
editor.setValue('new code')

// 获取选中的内容
const selection = editor.getSelection()
const selectedText = editor.getModel().getValueInRange(selection)

// 插入内容
editor.executeEdits('', [{
  range: editor.getSelection(),
  text: 'inserted text'
}])

// 格式化代码
editor.getAction('editor.action.formatDocument').run()

// 撤销
editor.trigger('keyboard', 'undo', null)

// 重做
editor.trigger('keyboard', 'redo', null)

// 查找
editor.getAction('actions.find').run()

// 替换
editor.getAction('editor.action.startFindReplaceAction').run()

基于 MIT 许可发布