由于第一次使用代码编辑器插件,之前都没接触过,花了几天时间才做出来满意的,参考了好几个大佬的文章,大家有需要可以自行查找相关文章!另外文底也献上了个别的参考文章。
一、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
好啦,本人有点懒,文章写得可能还不够详细。