由于第一次使用代码编辑器插件,之前都没接触过,花了几天时间才做出来满意的,参考了好几个大佬的文章,大家有需要可以自行查找相关文章!另外文底也献上了个别的参考文章。
一、vue-codemirror编辑器
vue2版本
vue2版本不支持最新的vue-codemirror,所以要下载固定的版本4.0.6,并且要搭配codemirror使用,codemirror也不建议使用6以上的版本
pnpm add codemirror@5.65.12 vue-codemirror@4.0.6
然后在main.js中全局挂载vuecodemirror
//codemirror
import VueCodemirror from 'vue-codemirror'
import 'codemirror/lib/codemirror.css'
Vue.use(VueCodemirror)
在要展示codemirror的页面,导入以下文件,包括有语言文件JavaScript,主体样式eclipse,和代码折叠所需的文件fold/xxx
import { codemirror } from 'vue-codemirror'
import 'codemirror/theme/eclipse.css'
import "codemirror/mode/javascript/javascript.js";
import 'codemirror/addon/fold/foldgutter.css'
import 'codemirror/addon/fold/foldcode'
import 'codemirror/addon/fold/foldgutter.js'
import 'codemirror/addon/fold/xml-fold'
import 'codemirror/addon/fold/brace-fold'
import 'codemirror/addon/fold/indent-fold'
import "codemirror/addon/hint/javascript-hint.js";
import "codemirror/addon/selection/active-line.js"
需要更改语言或者主体样式的,可以再node_modules里面找到相应文件import导入使用即可
添加配置项,这里存在一个bug就是自动补全括号无法实现,有看到的友友成功实现的话,可以评论区踢一下我
data () {
return {
curCode: '',
cmOptions: {
value: this.curCode,
autorefresh: true,
tabSize: 4, //tab空格宽度
mode: 'text/javascript',
line: true,
viewportMargin: Infinity, //处理高度自适应时搭配使用
highlightDifferences: true,
spellcheck: true,
autofocus: true,
indentWithTab: true,
smartIndent: true,
styleActiveLine: true, // 设置光标所在行高亮
showCursorWhenSelecting: true,
lineNumbers: true, // 显示行号
// matchBrackets: true, //自动补全括号
// autoCloseBrackets: true,
foldGutter: true, //代码折叠
gutters: ["CodeMirror-linenumbers", 'CodeMirror-foldgutter'],
theme: "eclipse",
},
}
},
最后就是使用了,大家也可以自行设置需要的样式
<div style="width: 600px;height: 300px; border: 1px solid #e5e5e5;" >
<codemirror ref="mycode"
v-model="curCode"
:options="cmOptions"
class="code"
style="width: 100%;height: 100%;"
@change="handleEdit"
>
</codemirror>
</div>
附上全部源码
<template>
<div style="width: 600px;height: 300px; border: 1px solid #e5e5e5;" >
<codemirror ref="mycode"
v-model="curCode"
:options="cmOptions"
class="code"
style="width: 100%;height: 100%;"
@change="handleEdit"
>
</codemirror>
</div>
</template>
<script>
import { codemirror } from 'vue-codemirror'
import 'codemirror/theme/eclipse.css'
import "codemirror/mode/javascript/javascript.js";
import 'codemirror/addon/fold/foldgutter.css'
import 'codemirror/addon/fold/foldcode'
import 'codemirror/addon/fold/foldgutter.js'
import 'codemirror/addon/fold/xml-fold'
import 'codemirror/addon/fold/brace-fold'
import 'codemirror/addon/fold/indent-fold'
import "codemirror/addon/hint/javascript-hint.js";
import "codemirror/addon/selection/active-line.js"
export default {
name: "HelloWord",
components: {codemirror},
data () {
return {
curCode: '',
cmOptions: {
value: this.curCode,
autorefresh: true,
tabSize: 4, //tab空格宽度
mode: 'text/javascript',
line: true,
viewportMargin: Infinity, //处理高度自适应时搭配使用
highlightDifferences: true,
spellcheck: true,
autofocus: true,
indentWithTab: true,
smartIndent: true,
styleActiveLine: true, // 设置光标所在行高亮
showCursorWhenSelecting: true,
lineNumbers: true, // 显示行号
// matchBrackets: true, //自动补全括号
// autoCloseBrackets: true,
foldGutter: true,
gutters: ["CodeMirror-linenumbers", 'CodeMirror-foldgutter'],
theme: "eclipse",
},
}
},
methods: {
handleEdit() {
console.log('44');
},
}
}
</script>
<style>
.code {
text-align: left;
font-size: 16px;
font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
}
</style>
效果图如下:
vue3版本
需要下载最新版本的vue-codemirror和codemirror
"vue-codemirror": "^6.1.1",
"codemirror": "^6.0.1",
紧接着下载语言包和主题包
# CodeMirror languages...
pnpm add @codemirror/lang-html
pnpm add @codemirror/lang-json
pnpm add @codemirror/lang-javascript
# CodeMirror themes...
pnpm add @codemirror/theme-one-dark
页面中使用的全部代码
<template>
<codemirror
v-model="code"
placeholder="Code goes here..."
:style="{ height: '400px' }"
:autofocus="true"
:indent-with-tab="true"
:tab-size="2"
:extensions="extensions"
@ready="handleReady"
@change="log('change', $event)"
@focus="log('focus', $event)"
@blur="log('blur', $event)"
/>
</template>
<script>
import { defineComponent, ref, shallowRef } from 'vue'
import { Codemirror } from 'vue-codemirror'
import { javascript } from '@codemirror/lang-javascript'
import { oneDark } from '@codemirror/theme-one-dark'
export default defineComponent({
components: {
Codemirror
},
setup() {
const code = ref(`console.log('Hello, world!')`)
const extensions = [javascript(), oneDark]
// Codemirror EditorView instance ref
const view = shallowRef()
const handleReady = (payload) => {
view.value = payload.view
}
// Status is available at all times via Codemirror EditorView
const getCodemirrorStates = () => {
const state = view.value.state
const ranges = state.selection.ranges
const selected = ranges.reduce((r, range) => r + range.to - range.from, 0)
const cursor = ranges[0].anchor
const length = state.doc.length
const lines = state.doc.lines
// more state info ...
// return ...
}
return {
code,
extensions,
handleReady,
log: console.log
}
}
})
</script>
在main.js全局中挂载并设置配置项
import { basicSetup } from 'codemirror'
import VueCodemirror from 'vue-codemirror'
const app = createApp()
app.use(VueCodemirror, {
// optional default global options
autofocus: true,
disabled: false,
indentWithTab: true,
tabSize: 2,
placeholder: 'Code goes here...',
extensions: [basicSetup]
// ...
})
想要白色背景的codemirror,只要去掉oneDark主题就可以了,导入这个主题样式就是黑色背景
效果图如下:
还发现一个bug就是,在编辑状态的时候会自动添加一层虚线框,找了好久也没发现有设置样式,最后发现overflow:hidden可以隐藏掉虚线框,真是被自己蠢到了~
二、aceEditor编辑器
下载:
pnpm add ace-builds
代码:参考的一个大佬的,但是文章被关掉了,大家可以自己去找找
<template>
<div class="ace">
<div ref="ace" class="ace-editor"/>
</div>
</template>
<script>
//ace-editor
import ace from 'ace-builds'
// ace主题包
import 'ace-builds/src-min-noconflict/theme-eclipse'
// ace 检索框
import 'ace-builds/src-min-noconflict/ext-searchbox'
// ace语言包
import 'ace-builds/src-min-noconflict/mode-javascript'
import 'ace-builds/src-min-noconflict/mode-json5'
//代码完成
import 'ace-builds/src-min-noconflict/ext-language_tools'
export default {
name: 'AceDemo',
data() {
return {
editor: null
}
},
mounted() {
ace.config.set("basePath", "https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.14/");
//快速开始-demo
this.editor = ace.edit(this.$refs.ace, {
maxLines: 17, // 最大行数,超过会自动出现滚动条
// minLines: 1, // 最小行数,还未到最大行数时,编辑器会自动伸缩大小
fontSize: 14, // 编辑器内字体大小
theme: 'ace/theme/eclipse', // 默认设置的主题
mode: 'ace/mode/javascript', // 默认设置的语言模式
tabSize: 4,// 制表符设置为 4 个空格大小
readOnly: false, //只读
useWorker: false, //取消语法检测
});
},
methods: {
// 填充值
fillValue: function () {
this.editor.setValue("hello world", -1)
},
getLineNum: function () {
let lineNum = this.editor.session.getLength();
alert("总行数为:" + lineNum)
},
getLineAndRow: function () {
let cursor = this.editor.selection.getCursor();
alert("当前光标所在行列:" + JSON.stringify(cursor))
},
// 光标跳转到第几行第几列
gotoLine: function () {
this.editor.gotoLine(1, 1);
},
}
}
</script>
<style scoped>
.ace {
width: 100%;
height: 300px;
border: 1px solid #ddd;
overflow: hidden;
display: flex;
}
.ace-editor {
width: 100%;
height: 100%;
margin-bottom: 20px;
}
.ace-toolbar {
display: flex;
justify-content: center;
margin-top: 20px;
}
.ace-toolbar > button {
margin-left: 20px;
}
:deep(.ace-eclipse .ace_gutter) {
background-color: #fff;
border-right: 0;
}
:deep(.ace_gutter-active-line) {
background-color: #fff;
}
</style>
效果图如下:
三、monaco编辑器
这个插件和前面两种略有不同,右边会有一个小的回显,可以点击、拖动,类似vscode
下载:这两个插件有版本对应要求,可以自行去查询
"monaco-editor": "^0.31.0",
"monaco-editor-webpack-plugin": "^7.1.0",
在vue.config.js中引入monaco-editor-webpack-plugin,然后添加配置项
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: {
plugins: [
new MonacoWebpackPlugin(),
],
}
})
代码:
这里使用了自定义语言,如果有需要使用官方语言如javascript、python等,把自定义语言开始到结束的部分去掉,然后将language语言支持换成javascript就可以啦。
<template>
<div id="editor" style="height: 300px;"></div>
</template>
<script setup>
import * as monaco from 'monaco-editor'
import { ref, toRaw, nextTick } from 'vue'
const editor = ref(null)
// 自定义语言开始
monaco.languages.register({ id: 'mySpecialLanguage' });
// 给自定义语言添加自动补全括号
monaco.languages.setLanguageConfiguration('mySpecialLanguage', {
comments: {
lineComment: '//',
blockComment: ['/*', '*/']
},
brackets: [['{', '}'], ['[', ']'], ['(', ')']],
autoClosingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' },
{ open: '"', close: '"', notIn: ["string"] },
{ open: "'", close: "'", notIn: ["string", "comment"] },
{ open: "`", close: "`", notIn: ["string", "comment"] },
{ open: "/**", close: " */", notIn: ["string"] },
],
surroundingPairs: [
{ open: '{', close: '}' },
{ open: '[', close: ']' },
{ open: '(', close: ')' }
]
});
// 给自定义语言添加匹配规则
monaco.languages.setMonarchTokensProvider('mySpecialLanguage', {
tokenizer: {
root: [
[/\bif\b/, 'keyword'],
[/\b\d+\b/, 'number'],
[/\b(a|an|the)\b/, 'article'],
[/[a-z][a-z0-9]*/, 'identifier'],
[/[A-Z][a-z0-9]*/, 'type.identifier'],
[/'([^'\\]|\\.)*'/, 'string'],
[/"/, 'string', '@string']
],
string: [
[/[^\\"]+/, 'string'],
[/\\./, 'string.escape'],
[/"/, 'string', '@pop']
]
}
});
// 自定义语言结束
const initEditor = () => {
editor.value = monaco.editor.create(document.querySelector('#editor'), {
value: '', //编辑器初始显示文字
language: 'mySpecialLanguage', //语言支持
theme: 'vs', //主题
selectOnLineNumbers: true,//显示行号
roundedSelection: false,
readOnly: false, // 只读
cursorStyle: 'line', //光标样式
automaticLayout: true, //自动布局
glyphMargin: true, //字形边缘
useTabStops: false,
fontSize: 18, //字体大小
autoIndent: true, //自动布局
quickSuggestionsDelay: 100, //代码提示延时
});
// 监听值的变化
// editor.value.onDidChangeModelContent((val) => {
// console.log(val.changes[0].text)
// })
}
nextTick(() => {
initEditor()
})
// 获取编辑器中的文本
const getEditorValue = () => {
const value = toRaw(editor.value).getValue()
// console.log(value);
}
// 修改编辑器的文本
const setEditorValue = (val) => {
toRaw(editor.value).getModel().setValue(val)
}
</script>
效果图如下:
参考的大佬文章:
https://github.com/surmon-china/vue-codemirror
https://blog.csdn.net/weixin_43977534/article/details/123822431
https://www.cnblogs.com/wangjiahui/p/15524189.html
好啦,本人有点懒,文章写得可能还不够详细。