需求:想要实现一个类似vscode中代码对比的功能
问了大佬,大佬说monaco-eidtor会比较好用一些,于是在项目中就使用了monaco-eidtor这个编辑器
monaco-eidtor
微软之前有个项目叫做Monaco Workbench,后来这个项目变成了VSCode,而Monaco Editor(下文简称monaco)就是从这个项目中成长出来的一个web编辑器,所以monaco和VSCode在编辑代码,交互以及UI上几乎是一摸一样的,只不过vscode性能、功能上更强大健全。
使用
安装
npm install monaco-editor --save
npm install monaco-editor-webpack-plugin --save //这个必须安装,不然起不来
配置文件(我网上查了好多参考文档,大佬们都写了这一步,但实际开发中,这一步我并没有用到)
修改vue.config.js配置文件
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
module.exports = {
...
plugins: [
...
new MonacoWebpackPlugin()
]
};
开始使用
子组件
<template>
<div ref="container" class="monaco-editor monacoBorder" :style="'height: ' + height + 'px'"></div>
</template>
<script>
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api.js';
export default {
name: 'AcMonaco',
props: {
language: {
type: String,
default: 'json'
},
oldValue: String,
value: String,
is_readOnly: Boolean,
height: {
type: Number,
default: 400
}
},
data() {
return {
monacoDiffInstance: '',
// 主要配置
defaultOpts: {
value: '',
theme: 'vs', // 编辑器主题:vs, hc-black, or vs-dark,更多选择详见官网
roundedSelection: false, // 右侧不显示编辑器预览框
autoIndent: true, // 自动缩进
automaticLayout: true, // 自适应布局
readOnly: true, // 是否只读
folding: true, // 是否启用代码折叠
scrollBeyondLastLine: false // 设置编辑器是否可以滚动到最后一行之后
},
originalModel: '',
modifiedModel: ''
};
},
mounted() {
this.init();
},
// 监听父组件传值的变化,实时更新到编辑器中
watch: {
oldValue: {
handler: function (val, oldVal) {
this.originalModel = monaco.editor.createModel(val, this.language);
this.monacoDiffInstance.setModel({
original: this.originalModel,
modified: this.modifiedModel
});
}
},
value: {
handler: function (val, oldVal) {
this.modifiedModel = monaco.editor.createModel(val, this.language);
this.monacoDiffInstance.setModel({
original: this.originalModel,
modified: this.modifiedModel
});
this.$emit('func', this.modifiedModel.getValue());
}
}
},
methods: {
init() {
// 初始化编辑器实例
this.$nextTick(() => {
this.defaultOpts.readOnly = this.is_readOnly;
this.monacoDiffInstance = monaco.editor.createDiffEditor(this.$refs['container'], this.defaultOpts);
this.originalModel = monaco.editor.createModel(this.oldValue, this.language);
this.modifiedModel = monaco.editor.createModel(this.value, this.language);
this.monacoDiffInstance.setModel({
original: this.originalModel,
modified: this.modifiedModel
});
});
},
// 此方法获取到编辑的最新值,传给父组件
getValue() {
this.$emit('func', this.modifiedModel.getValue());
}
}
};
</script>
<style lang="scss" scoped>
.the-code-diff-editor-container {
width: 100%;
height: 100%;
overflow: auto;
.monaco-editor .scroll-decoration {
box-shadow: none;
}
}
.monacoBorder {
border: 1px solid #e2e2e1;
}
</style>
父组件
<div>
<monaco ref="monaco" :oldValue="editCodeValue" :value="newValue" :is_readOnly="false" @func="getNewValue"></monaco>
</div>
import monaco from '../../components/monaco.vue';
components: {
monaco
},
components: {
monaco
},
// diff获取修改后的值
getNewValue(val) {
this.newValue = val;
}
更改is_readOnly的值可以使编辑器只读或者可编辑,当编辑器可编辑的时候,就能实现代码修改前后对比,这样需求就基本实现了。