相信写OJ的小伙伴都会遇到一个问题,那就是在线编辑器的实现。到底要选哪个呢
其实开源的编辑器有挺多的比如Ace、CodeMirror、MonacoEditor、CodeFlask、EditArea。详细的可以看看这个Top 5: 用Javascript编写的最佳代码编辑器插件, Top 5: Best code editor plugins written in Javascript
我第一个用的是MonacoEditor,这东西对webpack最新版跟webpack会起冲突,当时搞了我一下午,我也不知道前一天晚上是怎么成功的。。。
接着我又翻到了一些较为详细的Ace使用文档,然后对比了一下发现与AcWing是一样的,hhh。这让我瞬间来了动力。记得当时是先用了基于vue二次开发的,但是文档都不是很清楚,所以后来就直接用官方的了。顺带提一下qdoj用的是CodeMirror。
话不多说我们先看看效果图吧(完全和AcWing一样,2333
我用的是Element-ui,其实这些实现起来不是特别难,但是对于我这个后端废物来说,还是花了我很多时间的,有一说一,前端还是挺麻烦的。
那接着就上代码吧
我就只给编辑器的代码好了,不然太多就显得一团糟,毕竟我还没把它们分出来,哈哈哈
// 首先html部分就这么一行,ref是vue选中标签需要给上的属性,看到的文档都说不要用id,说是会有问题,感兴趣的小伙伴也可以试试
<div ref="ace" class="ace"></div>
<script>
// 导入需要的包
import ace from 'ace-builds'
import 'ace-builds/webpack-resolver'; // 在 webpack 环境中使用必须要导入
//解决添加提示时控制台警告(提示必须引入的包)
import "ace-builds/src-noconflict/ext-language_tools"
import "ace-builds/src-noconflict/ext-emmet"
//语言提示
import 'ace-builds/src-noconflict/snippets/javascript'
import 'ace-builds/src-noconflict/snippets/c_cpp'
import 'ace-builds/src-noconflict/snippets/java'
import 'ace-builds/src-noconflict/snippets/golang'
import 'ace-builds/src-noconflict/snippets/python'
//输入类型
import 'ace-builds/src-noconflict/keybinding-emacs'
import 'ace-builds/src-noconflict/keybinding-vim'
import 'ace-builds/src-noconflict/keybinding-vscode'
//以下是在vue中使用,其余的自己根据文档更改
export default {
name: 'CodeEditor',
props: {
value: {
type: String,
required: true
}
},
data() {
return {
themeValue: 'ambiance',
aceEditor: null,
themePath: 'ace/theme/monokai', // 不导入 webpack-resolver,该模块路径会报错
modePath: 'ace/mode/c_cpp', // 同上
codeValue: this.value || ''
}
}
mounted() {
this.aceEditor = ace.edit(this.$refs.ace,{
maxLines: 1000, // 最大行数,超过会自动出现滚动条
minLines: 22, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小
fontSize: 14, // 编辑器内字体大小
theme: this.themePath, // 默认设置的主题
mode: this.modePath, // 默认设置的语言模式
tabSize: 4, // 制表符设置为 4 个空格大小
readOnly: false, //只读
highlightActiveLine: true,
value: this.codeValue
});
this.aceEditor.setOptions({
enableSnippets: true,
enableLiveAutocompletion: true,
enableBasicAutocompletion: true
});
// 快捷键
// this.aceEditor.commands.addCommand({
// name: 'myCommand',
// bindKey: {win: 'Ctrl-M', mac: 'Command-M'},
// exec: function(editor) {
// //...
// },
// readOnly: true // false if this command should not apply in readOnly mode
// });
}
}
</script>
<style scoped lang="scss">
.ace {
position: relative !important;
border: 1px solid lightgray;
margin: auto;
height: auto;
width: 100%;
}
</style>
引用组件时记得绑定value
<CodeEditor v-bind:value="''"></CodeEditor>
想了一下还是给全部代码吧,因为我没有拆分,所以全部代码就是我截图的整个页面
<template>
<div class="Ace">
<div class="code_tool_bar">
<span style="position: relative;left: 10px; top: 16px; font-size: 18px;">写代码啦</span>
<el-button icon="el-icon-s-tools" @click="dialogTableVisible = true" style="float: right;margin: 10px;"></el-button