monaco-editor搭配Vue
方式一:Vue2安装(此版本已验证可使用)
npm install monaco-editor@0.30.1
npm install monaco-editor-webpack-plugin@6.0.0
vue.config.js配置
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
module.exports = defineConfig({
transpileDependencies: true,
//关闭eslint
lintOnSave: false,
configureWebpack: {
plugins: [new MonacoWebpackPlugin()],
},
})
方式二:index.html 利用CDN引入(推荐)
<!-- monaco编辑器 -->
<link rel="stylesheet" data-name="vs/editor/editor.main"
href="https://cdn.staticfile.org/monaco-editor/0.33.0/min/vs/editor/editor.main.css">
<script>self.require = { paths: { 'vs': 'https://cdn.staticfile.org/monaco-editor/0.33.0/min/vs' }, 'vs/nls': { availableLanguages: { '*': 'zh-cn' } } };</script>
<script src="https://cdn.staticfile.org/monaco-editor/0.33.0/min/vs/loader.min.js"></script>
<script src="https://cdn.staticfile.org/monaco-editor/0.33.0/min/vs/editor/editor.main.nls.zh-cn.js"></script>
<script src="https://cdn.staticfile.org/monaco-editor/0.33.0/min/vs/editor/editor.main.js"></script>
封装组件CodeEditor
<template>
<div class="editor-container">
<div class="toolbar">
<Select v-model="language" placeholder="请选择文件类型" style="width: 150px; padding-right: 10px">
<Option :value="item" v-for="item in languages">{{ item }}</Option>
</Select>
<a class="space" @click="handleCopy">一键复制</a>
<a class="space" @click="exportFile">导出文件</a>
</div>
<div ref="main" class="code-editor-container"></div>
</div>
</template>
<script>
import * as monaco from 'monaco-editor'
import FileSaver from 'file-saver'
export default {
name: 'CodeEditor',
props: {
language: {
type: String,
required: true,
},
value: {
type: String,
default: '',
},
},
data() {
return {
monacoEditor: null,
// 支持的语言
languages: ['txt', 'js', 'xml', 'java'],
}
},
watch: {
value(newCode) {
if (this.monacoEditor && newCode !== this.monacoEditor.getValue()) {
this.monacoEditor.setValue(newCode)
}
},
},
mounted() {
this.$nextTick(() => {
this.initMonaco()
})
},
methods: {
initMonaco() {
this.monacoEditor = monaco.editor.create(this.$refs.main, {
theme: 'vs-dark', // 主题
value: this.value, // 默认显示的值
language: this.language,
folding: true, // 是否折叠
foldingHighlight: true, // 折叠等高线
foldingStrategy: 'auto', // 折叠方式
showFoldingControls: 'always', // 是否一直显示折叠
disableLayerHinting: true, // 等宽优化
emptySelectionClipboard: false, // 空选择剪切板
selectionClipboard: true, // 选择剪切板
automaticLayout: true, // 自动布局
codeLens: true, // 代码镜头
scrollBeyondLastLine: false, // 滚动完最后一行后再滚动一屏幕
colorDecorators: true, // 颜色装饰器
accessibilitySupport: 'on', // 辅助功能支持"auto" | "off" | "on"
lineNumbers: 'on', // 行号 取值: "on" | "off" | "relative" | "interval" | function
lineNumbersMinChars: 4, // 行号最小字符 number
enableSplitViewResizing: false,
readOnly: false, //是否只读 取值 true | false
fontSize: 18,
})
// 使用 requestAnimationFrame 包装 onDidChangeModelContent
this.monacoEditor.onDidChangeModelContent(() => {
requestAnimationFrame(() => {
this.$emit('change', this.monacoEditor.getValue())
})
})
},
handleCopy() {
const currentValue = this.monacoEditor.getValue()
this.$copyText(currentValue).then(() => {
this.$Message.success('复制成功')
})
},
exportFile: function () {
const content = this.monacoEditor.getValue()
const blob = new Blob([content], { type: 'text/plain;charset=utf-8;' })
const fileName = `code` + new Date().getTime() + `.${this.language}`
FileSaver.saveAs(blob, fileName)
},
},
}
</script>
<style scoped>
.code-editor-container {
width: 100%;
height: 100%;
text-align: initial;
}
.toolbar {
display: flex;
justify-content: flex-end;
text-align: initial;
padding: 2px 10px;
background: #333;
color: white;
}
.space {
padding-right: 16px;
margin: auto 0;
}
</style>
测试使用
<template>
<div>
<CodeEditor language="xml" v-model="code" @change="codeChange" style="height: 50vh" />
</div>
</template>
<script>
import CodeEditor from '@/monaco/CodeEditor'
export default {
components: {
CodeEditor,
},
data() {
return {
code: 'hello world',
}
},
methods: {
codeChange(e) {
console.log(e)
},
},
}
</script>
效果