简介
这是基于 Vue 3 开发的 CodeMirror 组件。该组件基于 CodeMirror 5 开发,仅支持 Vue 3。
除了支持官方提供的各种语法模式外,还额外添加了日志输出展示模式,开箱即用,但不一定适用于所有场景。
如需完整文档和更多使用案例,请查阅 codemirror-editor-vue3 的官方文档。
安装
npm install codemirror-editor-vue3 codemirror@^5 -S
yarn add codemirror-editor-vue3 codemirror@">=5.64.0 <6"
pnpm i codemirror-editor-vue3 codemirror@^5 -S
如果你的项目需要支持 TypeScript,则还需要安装 @types/codemirror 依赖。
npm install @types/codemirror -D
注册全局组件
不推荐全局注册组件,这会导致模板中的类型提示无法正确获取。
main.js:
import { createApp } from "vue";
import App from "./App.vue";
import { InstallCodeMirror } from "codemirror-editor-vue3";
const app = createApp(App);
app.use(InstallCodeMirror);
app.mount("#app");
全局注册的组件名称是Codemirror,或者您可以自定义组件名称,例如:
app.use(InstallCodeMirror, { componentName: "customName" });
在组件中使用
<template>
<Codemirror
v-model:value="code"
:options="cmOptions"
border
placeholder="test placeholder"
:height="200"
@change="change"
/>
</template>
<script>
import Codemirror from "codemirror-editor-vue3";
// placeholder
import "codemirror/addon/display/placeholder.js";
// language
import "codemirror/mode/javascript/javascript.js";
// placeholder
import "codemirror/addon/display/placeholder.js";
// theme
import "codemirror/theme/dracula.css";
import { ref } from "vue";
export default {
components: { Codemirror },
setup() {
const code = ref(`
var i = 0;
for (; i < 9; i++) {
console.log(i);
// more statements
}`);
return {
code,
cmOptions: {
mode: "text/javascript", // Language mode
theme: "dracula", // Theme
},
};
},
};
</script>
语法高亮
常用语法
- javascript
- json
- css
- html
- apl
- yaml
更多的案例正在逐渐增加,您也可以参考文档来实现更多的语言模式。
自定义语法高亮
自定义语法文件custom-js-mode
import { javascript } from "codemirror/mode/javascript/javascript";
export function defineCustomMode(CodeMirror) {
CodeMirror.defineMode("custom-javascript", function(config, parserConfig) {
const jsMode = CodeMirror.getMode(config, "text/javascript");
return {
startState: function() {
return {
jsState: jsMode.startState(),
};
},
token: function(stream, state) {
if (stream.match(/^$([^$]*)\]/)) {
return "bracket-content";
}
if (stream.match(/^[A-Za-z_][A-Za-z0-9_]*(?=\s*$|\s*[({=;])/)) {
return "english-word";
}
return jsMode.token(stream, state.jsState);
},
indent: jsMode.indent,
electricInput: jsMode.electricInput,
fold: jsMode.fold,
closeBrackets: jsMode.closeBrackets,
};
});
}
在组件中使用自定义语法模式
<template>
<Codemirror
v-model:value="code"
:options="cmOptions"
border
placeholder="test placeholder"
:height="200"
@change="change"
/>
</template>
<script>
import Codemirror from "codemirror-editor-vue3";
// placeholder
import "codemirror/addon/display/placeholder.js";
// language
import "codemirror/mode/javascript/javascript.js";
// placeholder
import "codemirror/addon/display/placeholder.js";
// theme
// import "codemirror/theme/dracula.css";
import "codemirror/theme/dracula.css";
// 引入自定义模式
import { defineCustomMode } from "./custom-js-mode"; // 替换为你实际路径
// 注册自定义模式
defineCustomMode(window.CodeMirror);
import { ref } from "vue";
export default {
components: { Codemirror },
setup() {
const code = ref(`
[一级渠道]ROW_MAX()`);
return {
code,
cmOptions: {
// mode: "log", // Language mode
// theme: "default", // Theme
// mode: "text/javascript", // Language mode
// theme: "dracula", // Theme
mode: "custom-javascript", // Language mode
theme: "dracula", // Theme
},
};
},
};
</script>
<style>
/* 在 style 部分添加以下样式 */
.cm-s-dracula span.cm-variable {
color: rgba(141,213,121,0.8) !important;
}
.cm-s-dracula span.cm-english-word {
color: rgba(216,78,224,0.8) !important;
}
</style>
配置项
name | description | type | default |
---|---|---|---|
value(v-model) | Editor content | string | “” |
options | Configuration options of codemirror5 | EditorConfiguration | DEFAULT_OPTIONS |
placeholder | Editor placeholder content to introduce codemirror related files | string | “” |
border | Whether to display editor borders | boolean | false |
width | Width | string | 100% |
height | Height | string | 100% |
original-style | Using the original style, disable the second modification of the style for this component (but does not affect width, height, and border) | boolean | false |
KeepCursorInEnd | Always keep the mouse position on the last line | boolean | false |
merge | Merge mode, can also be used as diff pattern | boolean | false |
事件
定义组件事件
下面三个仅仅是这个组件封装的事件。请参考更多事件代码镜像事件
event name | description | params |
---|---|---|
change | value or instance changes | (value: string, cm: Editor) => void |
input | input | (value: string) => void |
ready | The Codemirror component is mounted | (cm: Editor) => void |
Codemirror事件
以下事件是codemiror5的官方事件。您可以使用该组件直接通过组件绑定事件,例如:
<Codemirror
v-model:value="code"
:options="{ mode: 'text/x-vue', theme: 'default' }"
border
placeholder="test-placeholder"
:height="200"
@change="onChange"
@blur="onBlur"
@focus="onFocus"
@scroll="onScroll"
/>
全部事件
CodeMirror 提供了丰富的事件系统,使得开发者可以监听编辑器中的各种行为,并在这些行为发生时执行自定义的逻辑。以下是每个事件的简要说明和使用案例:
1. changes
- 描述:当文档内容发生变化时触发。
- 参数:
instance
:当前 CodeMirror 实例。changeObj
:包含变化信息的对象。
editor.on('changes', function(instance, changeObj) {
console.log("Changes detected:", changeObj);
});
2. scroll
- 描述:当滚动条位置改变时触发。
- 参数:
instance
当前 CodeMirror 实例。
editor.on('scroll', function(instance) {
console.log("Scroll position changed");
});
3. beforeChange
- 描述:在文档变更之前触发,允许阻止变更。
- 参数:
instance
:当前 CodeMirror 实例。changeObj
:变更对象,可修改以影响变更。
editor.on('beforeChange', function(instance, changeObj) {
console.log("Before change", changeObj.from, changeObj.to, changeObj.text);
});
4. cursorActivity
- 描述:光标或选区变化时触发。
- 参数:
instance
当前 CodeMirror 实例。
editor.on('cursorActivity', function(instance) {
console.log("Cursor or selection changed");
});
5. keyHandled
- 描述:当一个键被处理后触发。
- 参数:
instance
:当前 CodeMirror 实例。name
:按键名称。event
:原生键盘事件。
editor.on('keyHandled', function(instance, name, event) {
console.log("Key handled:", name);
});
6. inputRead
- 描述:每当从输入中读取到字符时触发。
- 参数:
instance
:当前 CodeMirror 实例。changeObj
:包含变更信息的对象。
editor.on('inputRead', function(instance, changeObj) {
console.log("Input read:", changeObj.text.join(""));
});
7. electricInput
- 描述:当点击输入(如自动缩进)发生时触发。
- 参数:
instance
当前 CodeMirror 实例。
editor.on('electricInput', function(instance, line) {
console.log("Electric input on line:", line);
});
8. beforeSelectionChange
- 描述:在选择变化前触发,允许修改选择范围。
- 参数:
instance
:当前 CodeMirror 实例。obj
:包含旧的新的选择信息。
editor.on('beforeSelectionChange', function(instance, obj) {
console.log("Before selection change:", obj.ranges);
});
9. viewportChange
- 描述:当视口变化时触发(比如滚动导致可见行变化)。
- 参数:
instance
:当前 CodeMirror 实例。from
:新的起始行号。to
:新的结束行号。
editor.on('viewportChange', function(instance, from, to) {
console.log("Viewport changed from", from, "to", to);
});
10. swapDoc
- 描述:当文档被替换时触发。
- 参数:
instance
当前 CodeMirror 实例。
editor.on('swapDoc', function(instance) {
console.log("Document swapped");
});
11. gutterClick
- 描述:当点击行号区域时触发。
- 参数:
instance
:当前 CodeMirror 实例。line
:点击的行号。gutter
:被点击的边栏类型。clickEvent
:鼠标事件。
editor.on('gutterClick', function(instance, line, gutter, clickEvent) {
console.log("Gutter clicked at line:", line);
});
12. gutterContextMenu
- 描述:当右键点击行号区域时触发。
- 参数:
instance
:当前 CodeMirror 实例。line
:右键点击的行号。gutter
:被点击的边栏类型。contextMenuEvent
:鼠标事件。
editor.on('gutterContextMenu', function(instance, line, gutter, contextMenuEvent) {
console.log("Gutter context menu opened at line:", line);
});
13. focus
- 描述:当编辑器获得焦点时触发。
- 参数:
instance
当前 CodeMirror 实例。
editor.on('focus', function(instance) {
console.log("Editor focused");
});
14. blur
- 描述:当编辑器失去焦点时触发。
- 参数:
instance
当前 CodeMirror 实例。
editor.on('blur', function(instance) {
console.log("Editor blurred");
});
15. refresh
- 描述:当编辑器刷新(重新计算布局)时触发。
- 参数:
instance
当前 CodeMirror 实例。
editor.on('refresh', function(instance) {
console.log("Editor refreshed");
});
16. optionChange
- 描述:当选项更改时触发。
- 参数:
instance
:当前 CodeMirror 实例。option
:更改的选项名。
editor.on('optionChange', function(instance, option) {
console.log("Option changed:", option);
});
17. scrollCursorIntoView
- 描述:当尝试将光标滚动到视图中时触发。
- 参数:
instance
:当前 CodeMirror 实例。event
:事件对象。
editor.on('scrollCursorIntoView', function(instance, event) {
console.log("Scrolling cursor into view");
});
18. update
- 描述:当编辑器更新时触发(包括任何可能需要重新绘制的内容变化)。
- 参数:
instance
当前 CodeMirror 实例。
editor.on('update', function(instance) {
console.log("Editor updated");
});
常用方法
CodeMirror 提供了丰富的 API 方法,允许开发者与编辑器进行交互、查询和修改其状态。以下是一些常用的 CodeMirror 方法及其简要说明:
基本方法
getValue()
- 获取当前文档的全部内容。
var content = editor.getValue();
setValue(content)
- 设置整个文档的内容。
editor.setValue("新的内容");
replaceSelection(replacement, collapse)
- 替换当前选中的文本或在光标位置插入文本。
editor.replaceSelection("插入的文本", "end"); // 在光标后插入文本
focus()
- 让编辑器获得焦点。
editor.focus();
setOption(option, value)
- 动态设置选项。
editor.setOption("readOnly", true);
getOption(option)
- 获取当前选项的值。
var readOnly = editor.getOption("readOnly");
光标和选择
getCursor(startOrEnd)
- 获取主光标的位置。可以指定获取开始(
"start"
)或结束("end"
)位置,默认为主光标位置。
var cursor = editor.getCursor(); // 获取主光标位置
- 获取主光标的位置。可以指定获取开始(
setCursor(line, ch, options)
- 设置光标位置到特定行和列(从0开始计数)。
editor.setCursor(2, 5); // 移动光标到第3行第6个字符
somethingSelected()
- 检查是否有文本被选中。
if (editor.somethingSelected()) { console.log("有文本被选中"); }
文档操作
lineCount()
- 返回文档总行数。
var lines = editor.lineCount();
getLine(n)
- 获取特定行的文本内容。
var lineContent = editor.getLine(0); // 获取第一行的内容
markText(from, to, className)
- 标记一段文本,并可为其应用样式。
var marker = editor.markText({line: 1, ch: 0}, {line: 1, ch: 5}, {className: "styled-background"});
滚动和视图控制
scrollIntoView(pos, margin)
- 将指定位置滚动到视图中,可选地添加一个额外的边距。
editor.scrollIntoView({line: 10, ch: 0}, 10); // 滚动到第11行并留出10px边距
refresh()
- 刷新编辑器视图,通常在DOM元素大小改变后调用。
editor.refresh();
高级功能
addKeyMap(map, bottom)
- 添加自定义快捷键映射。
editor.addKeyMap({"Ctrl-Space": completeFromHint()});
on(event, handler)
- 注册事件监听器。
editor.on('change', function(instance, changeObj) { console.log("文档发生了变化:", changeObj); });
这些只是CodeMirror提供的部分API方法,更多高级功能如搜索、替换、注释等也都有相应的API支持。具体使用时可以根据项目需求查阅官方文档以获得更详细的说明和示例代码。由于CodeMirror版本更新可能会带来API的变化,请确保参考的是适用于您所使用的CodeMirror版本的文档。
参考文档
https://github.com/rennzhang/codemirror-editor-vue3