Package Exports
- vue-use-monaco
Readme
vue-use-monaco
项目简介
vue-use-monaco 是一个结合 Vue、Monaco 编辑器和 Shiki 语法高亮的组合式函数库,专为流式输入更新和高效代码高亮而设计。它提供了完整的 Monaco 编辑器集成方案,适用于需要实时代码编辑和高亮的场景。
特性
- 🚀 开箱即用 - 基于 Vue 3 组合式 API 设计
- 🎨 Shiki 高亮 - 使用 Shiki 实现高效的语法高亮,支持 TextMate 语法和 VS Code 主题
- 🌓 主题切换 - 自动监听 isDark 模式变化,智能切换明暗主题
- 📝 流式更新 - 支持流式输入更新,实时响应代码变化
- 🗑️ 内存管理 - 自动销毁编辑器实例,避免内存泄漏
- 🔧 高度可配置 - 支持所有 Monaco 编辑器原生配置选项
- 🎯 TypeScript 支持 - 完整的 TypeScript 类型定义
安装
使用 pnpm 安装:
pnpm add vue-use-monaco使用 npm 安装:
npm install vue-use-monaco使用 yarn 安装:
yarn add vue-use-monaco基础使用
简单示例
<script setup lang="ts">
import { onMounted, ref, watch } from 'vue'
import { useMonaco } from 'vue-use-monaco'
const props = defineProps<{
code: string
language: string
}>()
const codeEditor = ref<HTMLElement>()
const { createEditor, updateCode, cleanupEditor } = useMonaco({
themes: ['vitesse-dark', 'vitesse-light'],
languages: ['javascript', 'typescript', 'vue', 'python'],
readOnly: false,
MAX_HEIGHT: 600,
})
// 创建编辑器实例
onMounted(async () => {
if (codeEditor.value) {
await createEditor(codeEditor.value, props.code, props.language)
}
})
// 监听代码和语言变化
watch(
() => [props.code, props.language],
([newCode, newLanguage]) => {
updateCode(newCode, newLanguage)
},
)
</script>
<template>
<div ref="codeEditor" class="monaco-editor-container" />
</template>
<style scoped>
.monaco-editor-container {
border: 1px solid #e0e0e0;
border-radius: 4px;
}
</style>完整配置示例
<script setup lang="ts">
import type { MonacoLanguage, MonacoTheme } from 'vue-use-monaco'
import { onMounted, ref } from 'vue'
import { useMonaco } from 'vue-use-monaco'
const editorContainer = ref<HTMLElement>()
const {
createEditor,
updateCode,
setTheme,
setLanguage,
getCurrentTheme,
getEditor,
getEditorView,
cleanupEditor,
} = useMonaco({
// 主题配置 - 至少需要两个主题(暗色/亮色)
themes: ['github-dark', 'github-light'],
// 支持的语言列表
languages: ['javascript', 'typescript', 'python', 'vue', 'json'],
// 编辑器最大高度
MAX_HEIGHT: 500,
// 是否只读
readOnly: false,
// 是否在创建前清理之前的资源
isCleanOnBeforeCreate: true,
// 创建前的钩子函数
onBeforeCreate: (monaco) => {
// 可以在这里注册自定义语言、主题等
console.log('Monaco editor is about to be created', monaco)
return [] // 返回需要清理的 disposable 对象数组
},
// Monaco 编辑器原生配置
fontSize: 14,
lineNumbers: 'on',
wordWrap: 'on',
minimap: { enabled: false },
scrollbar: {
verticalScrollbarSize: 10,
horizontalScrollbarSize: 10,
alwaysConsumeMouseWheel: false,
},
})
onMounted(async () => {
if (editorContainer.value) {
const editor = await createEditor(
editorContainer.value,
'console.log("Hello, Monaco!")',
'javascript',
)
console.log('Editor created:', editor)
}
})
// 主题切换
function switchTheme(theme: MonacoTheme) {
setTheme(theme)
}
// 语言切换
function switchLanguage(language: MonacoLanguage) {
setLanguage(language)
}
// 更新代码
function updateEditorCode(code: string, language: string) {
updateCode(code, language)
}
// 获取当前主题
const currentTheme = getCurrentTheme()
console.log('Current theme:', currentTheme)
// 获取 Monaco 静态 API
const monacoEditor = getEditor()
console.log('Monaco editor API:', monacoEditor)
// 获取编辑器实例
const editorInstance = getEditorView()
console.log('Editor instance:', editorInstance)
</script>
<template>
<div>
<div class="controls">
<button @click="switchTheme('github-dark')">暗色主题</button>
<button @click="switchTheme('github-light')">亮色主题</button>
<button @click="switchLanguage('typescript')">TypeScript</button>
<button @click="switchLanguage('python')">Python</button>
</div>
<div ref="editorContainer" class="editor" />
</div>
</template>API 参考
useMonaco(options?)
参数
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
MAX_HEIGHT |
number |
500 |
编辑器最大高度(像素) |
readOnly |
boolean |
true |
是否为只读模式 |
themes |
MonacoTheme[] |
['vitesse-dark', 'vitesse-light'] |
主题数组,至少包含两个主题 |
languages |
MonacoLanguage[] |
见默认语言列表 | 支持的编程语言数组 |
theme |
string |
- | 初始主题名称 |
isCleanOnBeforeCreate |
boolean |
true |
是否在创建前清理之前注册的资源 |
onBeforeCreate |
function |
- | 编辑器创建前的钩子函数 |
返回值
| 方法/属性 | 类型 | 描述 |
|---|---|---|
createEditor |
(container: HTMLElement, code: string, language: string) => Promise<MonacoEditor> |
创建并挂载编辑器到指定容器 |
cleanupEditor |
() => void |
销毁编辑器并清理容器 |
updateCode |
(newCode: string, codeLanguage: string) => void |
更新编辑器内容和语言 |
setTheme |
(theme: MonacoTheme) => void |
切换编辑器主题 |
setLanguage |
(language: MonacoLanguage) => void |
切换编辑器语言 |
getCurrentTheme |
() => string |
获取当前主题名称 |
getEditor |
() => typeof monaco.editor |
获取 Monaco 的静态 editor 对象 |
getEditorView |
() => MonacoEditor | null |
获取当前编辑器实例 |
支持的主题
包括但不限于:
vitesse-dark/vitesse-lightgithub-dark/github-lightdracula/dracula-softone-dark-pro/one-lighttokyo-nightmaterial-theme系列catppuccin系列- 以及更多...
支持的语言
包括但不限于:
javascript/typescript/jsx/tsxvue/html/css/scss/lesspython/java/csharp/cpp/rust/gojson/yaml/toml/xmlmarkdown/dockerfile- 以及 100+ 种语言...
配置说明
Vite 配置
在使用 Monaco 编辑器时,建议使用 vite-plugin-monaco-editor-esm 插件处理 Web Workers。
import path from 'node:path'
import vue from '@vitejs/plugin-vue'
// vite.config.js
import { defineConfig } from 'vite'
import monacoEditorPlugin from 'vite-plugin-monaco-editor-esm'
export default defineConfig({
plugins: [
vue(),
monacoEditorPlugin({
languageWorkers: [
'editorWorkerService',
'typescript',
'css',
'html',
'json',
],
customDistPath(root, buildOutDir, base) {
return path.resolve(buildOutDir, 'monacoeditorwork')
},
}),
],
})Webpack 配置
如果使用 Webpack,可以使用 monaco-editor-webpack-plugin:
// webpack.config.js
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
module.exports = {
plugins: [
new MonacoWebpackPlugin({
languages: ['javascript', 'typescript', 'css', 'html', 'json'],
}),
],
}最佳实践
1. 性能优化
// 只加载需要的语言,减少包体积
const { createEditor } = useMonaco({
languages: ['javascript', 'typescript'], // 只加载必要的语言
themes: ['vitesse-dark', 'vitesse-light'],
})2. 内存管理
<script setup>
import { onUnmounted } from 'vue'
const { createEditor, cleanupEditor } = useMonaco()
// 组件卸载时自动清理(useMonaco 内部已处理)
// 但如果需要手动清理,可以调用:
onUnmounted(() => {
cleanupEditor()
})
</script>3. 主题跟随系统
import { useDark } from '@vueuse/core'
const isDark = useDark()
const { createEditor, setTheme } = useMonaco({
themes: ['github-dark', 'github-light'],
})
// 主题会自动跟随 isDark 状态切换故障排除
1. 打包后编辑器无法显示
确保正确配置了 Monaco Editor 的 Web Workers(参考上面的 Vite/Webpack 配置)。
2. 主题不生效
检查主题名称是否正确,确保主题已在 themes 数组中注册。
3. 语言高亮不工作
确保语言已在 languages 数组中包含,并且 Shiki 支持该语言。
贡献
欢迎提交 Issue 或 PR 来改进此项目!
开发
# 克隆项目
git clone https://github.com/Simon-He95/vue-use-monaco.git
# 安装依赖
pnpm install
# 启动开发服务器
pnpm dev
# 构建
pnpm build☕
License
Sponsors
致谢
本项目感谢以下开源库的支持:
- Monaco Editor — 微软出品的强大代码编辑器内核
- Shiki — 基于 TextMate 语法和 VS Code 主题的代码高亮库
- Vue.js — 渐进式 JavaScript 框架
- @shikijs/monaco — Shiki 与 Monaco Editor 的集成