Vue 中使用 Monaco Editor
最近的使命就是,在找好用的代码编辑器🤪
尝试了codeMirror 感觉咋用咋不顺手,简单的代码编辑还能应付,复杂一点的配置就搞得头昏眼花🙄,而且和 vue 一起用简直命里犯冲🤬
机缘巧合就找到了救世主Monaco Editor
安装配置
npm i monaco-editor
npm install monaco-editor-webpack-plugin --save-dev
vue.config.js
文件配置
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
module.exports = {
chainWebpack: (config) => {
config.plugin('monaco').use(new MonacoWebpackPlugin())
}
}
代码编辑
用到了
"element-ui": "^2.15.6"
<template>
<div class="myEditor">
<el-form :inline="true" ref="form">
<el-form-item>
<el-select v-model="theme" size="mini" @change="themeChange" placeholder="主题">
<el-option
v-for="item in themeOption"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="language" size="mini" filterable @change="languageChange" placeholder="语言">
<el-option
v-for="item in languageOption"
:key="item.id"
:label="item.id"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
</el-form>
<div id="container" ref="container"></div>
</div>
</template>
<script>
import * as monaco from 'monaco-editor'
export default {
data () {
return {
themeOption: [
{
value: 'vs',
label: '默认'
},
{
value: 'hc-black',
label: '高亮'
},
{
value: 'vs-dark',
label: '深色'
}
],
languageOption: [],
theme: 'vs',
language: 'plaintext'
}
},
mounted () {
const self = this
self.initEditor()
self.languageOption = monaco.languages.getLanguages()
},
methods: {
initEditor () {
const self = this
const domEditor = document.getElementById('container')
self.monacoEditor = monaco.editor.create(domEditor, {
theme: self.theme,
readOnly: false,
automaticLayout: true
})
},
themeChange (val) {
monaco.editor.setTheme(val)
},
languageChange (val) {
monaco.editor.setModelLanguage(this.monacoEditor.getModel(), val)
}
}
}
</script>
<style scoped>
#container{
width: 100vw;
height: calc(100vh - 41px);
text-align: left;
}
.el-form-item{
margin-bottom: 0;
margin-left: 10px;
}
</style>
代码对比
用到了
"element-ui": "^2.15.6"
<template>
<div class="myEditor">
<el-form :inline="true" ref="form">
<el-form-item>
<el-select v-model="theme" size="mini" @change="themeChange" placeholder="主题">
<el-option
v-for="item in themeOption"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-select v-model="language" size="mini" filterable @change="languageChange" placeholder="比对语言">
<el-option
v-for="item in languageOption"
:key="item.id"
:label="item.id"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
<el-form-item style="float: right">
{{diffNum}}处差异
</el-form-item>
</el-form>
<div id="container" ref="container"></div>
</div>
</template>
<script>
import * as monaco from 'monaco-editor'
export default {
data () {
return {
themeOption: [
{
value: 'vs',
label: '默认'
},
{
value: 'hc-black',
label: '高亮'
},
{
value: 'vs-dark',
label: '深色'
}
],
languageOption: [],
theme: 'vs',
language: 'plaintext',
diffNum: 0
}
},
mounted () {
const self = this
self.initEditor()
self.setModel('', '')
self.languageOption = monaco.languages.getLanguages()
},
methods: {
initEditor () {
const self = this
const domEditor = document.getElementById('container')
self.monacoEditor = monaco.editor.createDiffEditor(domEditor, {
theme: self.theme,
readOnly: false,
domReadOnly: false,
originalEditable: true,
automaticLayout: true
})
self.monacoEditor.onDidUpdateDiff(()=>{
self.diffNum = this.monacoEditor.getLineChanges().length
})
},
themeChange (val) {
monaco.editor.setTheme(val)
},
languageChange (val) {
console.log(val);
monaco.editor.setModelLanguage(this.monacoEditor.getModel().original, val)
monaco.editor.setModelLanguage(this.monacoEditor.getModel().modified, val)
},
setModel (original, modified) {
this.monacoEditor.setModel({
original: monaco.editor.createModel(original, this.language),
modified: monaco.editor.createModel(modified, this.language)
})
}
}
}
</script>
<style scoped>
#container{
width: 100vw;
height: calc(100vh - 41px);
text-align: left;
}
.el-form-item{
margin-bottom: 0;
margin-left: 10px;
}
</style>
代码对比增加下一处差异功能
monaco提供的方法会直接跳转到指定的差异位置。
// 创建差异指南
self.diffNavigator = monaco.editor.createDiffNavigator(this.monacoEditor,{
alwaysRevealFirst:true
})
// 上一处差异
self.diffNavigator.previous()
// 下一处差异
self.diffNavigator.next()
右键面板增加操作
self.monacoEditor.addAction({
id: 'nextDiff', // 菜单项 id
label: '上一处差异', // 菜单项名称
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.PageUp], // 绑定快捷键,是 monacoEditor 自定义的对应关系
contextMenuGroupId: 'navigation', // 所属菜单的分组
run: () => self.nextDiff(), // 点击后执行的操作
})
self.monacoEditor.addAction({
id: 'nextDiff', // 菜单项 id
label: '下一处差异', // 菜单项名称
keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.PageDown], // 绑定快捷键
contextMenuGroupId: 'navigation', // 所属菜单的分组
run: () => self.nextDiff(), // 点击后执行的操作
})
部分配置解释
配置名称 | 功能 |
---|---|
automaticLayout | 自适应布局 |
readOnly | 只读 |
theme | 主题 |
originalEditable | 源比较代码可编辑(代码对比) |