vue-codemirror代码编辑器使用
参考链接:vue2 导入使用vue-codemirror详解-CSDN博客
1.安装 vue-codemirror
npm i vue-codemirror
// codemirror 需要与 vue-codemirror 同时安装
npm i codemirror
2.使用codemirror组件
<template>
<div class="code-box">
<codemirror
ref="codeMirror"
v-model="cmContent"
:options="cmOptions"
@ready="onCmReady"
@blur="onCmBlur"
/>
</div>
</template>
<script>
import { codemirror } from 'vue-codemirror';
// 引入主题和功能
import './theme';
// 引入jshint
import jshint from 'jshint';
export default {
name: 'PluginCode',
components: { codemirror },
props: {
code: {
type: String,
default: ''
},
fullScreen: {
type: Boolean,
default: false
}
},
data() {
return {
cmContent: this.code,
cmOptions: {
// Config配置
mode: 'text/javascript', // 模式
theme: 'idea', // 主题
indentUnit: 2, // 缩进位数
smartIndent: true, // 智能缩进
tabSize: 4, // 制表符
lineWrapping: true, // 自动换行
lineNumbers: true, // 显示行号
lint: { 'esversion': '6' }, // 语法提示
readOnly: false, // 是否只读
lineWiseCopyCut: true, // 复制或剪切时没有选择文本,那么自动选光标所在整行
spellcheck: true, // 拼写检查
autocorrect: true, // 自动补全
autofocus: false, // 是否在初始化时自动获取焦点
showCursorWhenSelecting: true, // 光标选中效果
gutters: ['CodeMirror-lint-markers', 'CodeMirror-linenumbers', 'CodeMirror-foldgutter'], // gutter的CSS配置
extraKeys: {
Tab: (cm) => {
if (cm.somethingSelected()) {
// 正向缩进文本
cm.indentSelection('add');
} else {
// 光标处插入 indentUnit 个空格
cm.replaceSelection(Array(cm.getOption('indentUnit') + 1).join(' '), 'end', '+input');
}
},
Esc: (cm) => {
cm.setOption('fullScreen', false);
this.$emit('update:fullScreen', false);
},
'Ctrl-S': (cm) => { cm.save(); },
'Ctrl-/': 'toggleComment'
},
dragDrop: true, // 允许拖放文件和图片到编辑器里
allowDropFileTypes: ['text/javascript'], // 默认为null。当设置此项时,只接收包含在此数组内的文件类型拖入编辑器
viewportMargin: 1000, // 视图中内容上方和下方要渲染的行数
// Addons配置
foldGutter: true, // 启用行槽中的代码折叠
matchBrackets: true, // 括号匹配
autoCloseBrackets: true, // 自动闭合符号
styleActiveLine: true, // 当前行背景高亮
styleSelectedText: true, // 高亮选中文字
hintOptions: { completeSingle: false } // 当匹配只有一项时, 是否自动补全
}
};
},
computed: {
cm() {
return this.$refs.codeMirror.codemirror;
}
},
watch: {
code: {
handler(val) {
if (val) this.cmContent = val;
},
immediate: true
},
fullScreen: {
handler(val) {
if (val) {
this.cm.setOption('fullScreen', !this.cm.getOption('fullScreen'));
this.cm.focus();
// 设置焦点在内容尾部
this.cm.setCursor(this.cm.lineCount(), 0);
}
},
immediate: true
}
},
beforeCreate() {
window.JSHINT = jshint.JSHINT;
},
beforeDestroy() {
this.$refs.codeMirror = null;
},
mounted() {},
methods: {
// 加载事件
onCmReady(cm) {
// 这里的 cm 对象就是 codemirror 对象,等于 this.$refs.codeMirror.codemirror
cm.on('inputRead', (cm, obj) => {
if (obj.text && obj.text.length > 0) {
const c = obj.text[0].charAt(obj.text[0].length - 1);
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
cm.showHint({ completeSingle: false });
}
}
});
},
// 失去焦点
onCmBlur() {
this.$emit('getCmContent', this.cmContent);
},
// 校验错误
onCmError(cm = this.cm) {
const marked = cm?.state?.lint?.marked;
if (marked?.length) {
const markError = marked.filter(m => m.className.includes('mark-error'));
if (markError?.length) {
// 设置焦点在错误位置
const item = markError[0]?.lines[0];
if (item) {
cm.focus();
const line = cm.getLineNumber(item);
cm.setCursor(line, item.text.length);
this.$modal.msgWarning(`当前插件开发脚本存在语法错误, 已定位至错误位置`);
return true;
}
}
}
return false;
}
}
};
</script>
<style scoped lang="scss">
::v-deep .CodeMirror {
font-size: 14px;
height: 350px;
&.cm-s-idea {
span.cm-def {
color: #aa0000;
}
}
&.CodeMirror-fullscreen {
z-index: 9999;
}
.CodeMirror-activeline-background {
background: #e8f2ff;
}
.CodeMirror-gutters {
background: #F6F6F6;
}
.CodeMirror-hints {
position: absolute;
z-index: 10;
overflow: hidden;
list-style: none;
margin: 0;
padding: 2px;
box-shadow: 2px 3px 5px rgba(0,0,0,.2);
border-radius: 3px;
border: 1px solid silver;
background: white;
font-size: 90%;
font-family: monospace;
max-height: 20em;
overflow-y: auto;
}
}
</style>
3.theme.js中引入样式
// 引入样式
import 'codemirror/lib/codemirror.css';
import 'codemirror/theme/idea.css';
// 引入语言
import 'codemirror/mode/javascript/javascript.js';
// 数据校验
import 'codemirror/addon/lint/lint.css';
import 'codemirror/addon/lint/lint.js';
import 'codemirror/addon/lint/javascript-lint.js';
// 代码折叠
import 'codemirror/addon/fold/foldgutter.css';
import 'codemirror/addon/fold/foldgutter.js';
import 'codemirror/addon/fold/foldcode.js';
import 'codemirror/addon/fold/brace-fold.js';
import 'codemirror/addon/fold/comment-fold.js';
import 'codemirror/addon/fold/indent-fold.js';
// 高亮选中
import 'codemirror/addon/selection/active-line.js';
import 'codemirror/addon/selection/mark-selection.js';
// 代码高亮
import 'codemirror/addon/hint/show-hint.css';
import 'codemirror/addon/hint/show-hint.js';
import 'codemirror/addon/hint/javascript-hint.js';
import 'codemirror/addon/hint/anyword-hint.js';
// 代码注释
import 'codemirror/addon/comment/comment.js';
import 'codemirror/addon/comment/continuecomment.js';
// 自动括号
import 'codemirror/addon/edit/matchbrackets.js';
import 'codemirror/addon/edit/closebrackets.js';
// 代码全屏
import 'codemirror/addon/display/fullscreen.css';
import 'codemirror/addon/display/fullscreen.js';
// 滚动条
import 'codemirror/addon/scroll/simplescrollbars.css';
import 'codemirror/addon/scroll/simplescrollbars.js';
// // 提示弹窗
// import 'codemirror/addon/dialog/dialog.css';
// import 'codemirror/addon/dialog/dialog.js';
// // 搜索功能
// import 'codemirror/addon/search/search.js';
// import 'codemirror/addon/search/searchcursor.js';
// import 'codemirror/addon/search/jump-to-line.js';
// import 'codemirror/addon/search/match-highlighter.js';