前提小结:
第一次用 codemirror, 而且是在 vue 里面使用, 看了官方文档, 一大串都是英文, 翻译后大概了解了这个插件, 然后在项目中使用时出现过好几个问题:
1. 新版的 codemirror 在 lib 目录下没有 codemirror.JS 文件, 旧版的有, 所以网上的很多文章都是直接这样引:
- <scriptsrc="lib/codemirror.js"></script>
- <linkrel="stylesheet"href="../lib/codemirror.CSS" rel="external nofollow">
- <scriptsrc="mode/javascript/javascript.js"></script>
然而新手在新版的 codemirror 怎么引都报错, 新版的 codemirror 把 codemirror.JS 放到了 src 目录下, 当然 src 目录下的 codemirror.JS 文件如果你要移到 lib 目录下是要改变里面的路径的.
2. 在 vue 里面使用 codemirror, 动态创建编辑器, 在关闭的时候会产生一种鬼知道是什么的错误, 就是比如我新建了 a,b 两个编辑器, a 在左, b 在右, 当我关闭 a 时, 想要显示 b 的文档内容, 却显示的是 b 的, 肯呢个这是动态数据改变产生的错误, 可是当关闭 b, 不关闭 a 时, 就能显示 a 的文本内容.
3. 路由跳转的时候, 当打开的编辑器代码显示最顶层的内容的时候, 切换到其他路由再切换回来还是能显示缓存的编辑器文本, 当我把编辑器拉到最底层, 显示最底层的文本内容, 再切换到其他路由再切回来时, 编辑器一片空白, 鼠标点击编辑器或者鼠标滑轮滚动, 文本内容出现, 而且显示的内容是顶层的内容.
基于以上几点, 我选择用 vue-codemirror 组件来实现.
实现
1. 首先要先安装 vue-codemirror
在 NPM 的官网我找到了 vue-codemirror
- https://www.npmjs.com/package/vue-codemirror
- NPM install vue-codemirror --save
接着在 main.JS 里使用
- import {
- codemirror
- } from 'vue-codemirror'
- import 'codemirror/lib/codemirror.css'
- Vue.use(VueCodemirror)
再到组件中使用
- import { codemirror } from 'vue-codemirror'
- require("codemirror/mode/python/python.js")
- require('codemirror/addon/fold/foldcode.js')
- require('codemirror/addon/fold/foldgutter.js')
- require('codemirror/addon/fold/brace-fold.js')
- require('codemirror/addon/fold/xml-fold.js')
- require('codemirror/addon/fold/indent-fold.js')
- require('codemirror/addon/fold/markdown-fold.js')
- require('codemirror/addon/fold/comment-fold.js')
当然组件需要先声明
- components:{
- codemirror
- }
html 代码这样写:
- <codemirror
- ref="myCm"
- :value="item.content"
- :options="cmOptions"
- @changes="changes"
- class="code"
- ></codemirror>
options 是和 codemirror 一样的配置项
value: string | CodeMirror.Doc
编辑器的初始值(文本), 可以是字符串或者 CodeMirror 文档对象(不同于 HTML 文档对象).
mode: string | object
通用的或者在 CodeMirror 中使用的与 mode 相关联的 mime, 当不设置这个值的时候, 会默认使用第一个载入的 mode 定义文件. 一般地, 会使用关联的 mime 类型来设置这个值; 除此之外, 也可以使用一个带有 name 属性的对象来作为值(如:{name: "javascript",
JSON: true}). 可以通过访问 CodeMirror.modes 和 CodeMirror.mimeModes 获取定义的 mode 和 MIME.
lineSeparator: string|null
明确指定编辑器使用的行分割符 (换行符). 默认(值为 null) 情况下, 文档会被 CRLF(以及单独的 CR, LF)分割, 单独的 LF 会在所有的输出中用作换行符(如: getValue). 当指定了换行字符串, 行就只会被指定的串分割.
theme: string
配置编辑器的主题样式. 要使用主题, 必须保证名称为 .cm-s-[name] (name 是设置的 theme 的值)的样式是加载上了的. 当然, 你也可以一次加载多个主题样式, 使用方法和 HTML 和使用类一样, 如: theme: foo bar, 那么此时需要 cm-s-foo cm-s-bar 这两个样式都已经被加载上了.
indentUnit: integer
缩进单位, 值为空格数, 默认为 2 .
smartIndent: boolean
自动缩进, 设置是否根据上下文自动缩进(和上一行相同的缩进量). 默认为 true.
tabSize: integer
tab 字符的宽度, 默认为 4 .
indentWithTabs: boolean
在缩进时, 是否需要把 n*tab 宽度个空格替换成 n 个 tab 字符, 默认为 false .
electricChars: boolean
在输入可能改变当前的缩进时, 是否重新缩进, 默认为 true (仅在 mode 支持缩进时有效).
specialChars: RegExp
需要被占位符 (placeholder) 替换的特殊字符的正则表达式. 最常用的是非打印字符. 默认为:/[\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/.
specialCharPlaceholder: function(char) → Element
这是一个接收由 specialChars 选项指定的字符作为参数的函数, 此函数会产生一个用来显示指定字符的 DOM 节点. 默认情况下, 显示一个红点(•), 这个红点有一个带有前面特殊字符编码的提示框.
- rtlMoveVisually: boolean
- Determines whether horizontal cursor movement through right-to-left (Arabic, Hebrew) text is visual (pressing the left arrow moves the cursor left) or logical (pressing the left arrow moves to the next lower index in the string, which is visually right in right-to-left
- text). The default is false on Windows, and true on other platforms.(这段完全不晓得搞啥子鬼)
- keyMap: string
配置快捷键. 默认值为 default, 即 codemorrir.JS 内部定义. 其它在 key
map 目录下.
extraKeys: object
给编辑器绑定与前面 keyMap 配置不同的快捷键.
lineWrapping: boolean
在长行时文字是换行 (wrap) 还是滚动(scroll), 默认为滚动(scroll).
lineNumbers: boolean
是否在编辑器左侧显示行号.
firstLineNumber: integer
行号从哪个数开始计数, 默认为 1 .
lineNumberFormatter: function(line: integer) → string
使用一个函数设置行号.
gutters: array<string>
用来添加额外的 gutter(在行号 gutter 前或代替行号 gutter). 值应该是 CSS 名称数组, 每一项定义了用于绘制 gutter 背景的宽度(还有可选的背景). 为了能明确设置行号 gutter 的位置(默认在所有其它 gutter 的右边), 也可以包含 CodeMirror-linenumbers 类. 类名是用于传给 setGutterMarker 的键名(keys).
fixedGutter: boolean
设置 gutter 跟随编辑器内容水平滚动 (false) 还是固定在左侧(true 或默认).
scrollbarStyle: string
设置滚动条. 默认为 "native", 显示原生的滚动条. 核心库还提供了 "null" 样式, 此样式会完全隐藏滚动条. Addons 可以设置更多的滚动条模式.
coverGutterNextToScrollbar: boolean
当 fixedGutter 启用, 并且存在水平滚动条时, 在滚动条最左侧默认会显示 gutter, 当此项设置为 true 时, gutter 会被带有 CodeMirror-gutter-filler 类的元素遮挡.
inputStyle: string
选择 CodeMirror 处理输入和焦点的方式. 核心库定义了 textarea 和 contenteditable 输入模式. 在移动浏览器上, 默认是 contenteditable, 在桌面浏览器上, 默认是 textarea. 在 contenteditable 模式下对 IME 和屏幕阅读器支持更好.
readOnly: boolean|string
编辑器是否只读. 如果设置为预设的值 "nocursor", 那么除了设置只读外, 编辑区域还不能获得焦点.
showCursorWhenSelecting: boolean
在选择时是否显示光标, 默认为 false.
lineWiseCopyCut: boolean
启用时, 如果在复制或剪切时没有选择文本, 那么就会自动操作光标所在的整行.
undoDepth: integer
最大撤消次数, 默认为 200(包括选中内容改变事件) .
historyEventDelay: integer
在输入或删除时引发历史事件前的毫秒数.
tabindex: integer
编辑器的 tabindex.
autofocus: boolean
是否在初始化时自动获取焦点. 默认情况是关闭的. 但是, 在使用 textarea 并且没有明确指定值的时候会被自动设置为 true.
低级选项
下面的选项仅用于一些特殊情况.
dragDrop: boolean
是否允许拖放, 默认为 true.
allowDropFileTypes: array<string>
默认为 null. 当设置此项时, 只接收包含在此数组内的文件类型拖入编辑器. 文件类型为 MIME 名称.
cursorBlinkRate: number
光标闪动的间隔, 单位为毫秒. 默认为 530. 当设置为 0 时, 会禁用光标闪动. 负数会隐藏光标.
cursorScrollMargin: number
当光标靠近可视区域边界时, 光标距离上方和下方的距离. 默认为 0 .
cursorHeight: number
光标高度. 默认为 1, 也就是撑满行高. 对一些字体, 设置 0.85 看起来会更好.
resetSelectionOnContextMenu: boolean
设置在选择文本外点击打开上下文菜单时, 是否将光标移动到点击处. 默认为 true.
workTime, workDelay: number
通过一个假的后台线程高亮 workTime 时长, 然后使用 timeout 休息 workDelay 时长. 默认为 200 和 300 .(完全不懂这个功能是在说啥)
pollInterval: number
指明 CodeMirror 向对应的 textarea 滚动 (写数据) 的速度 (获得焦点时). 大多数的输入都是通过事件捕获, 但是有的输入法(如 IME) 在某些浏览器上并不会生成事件, 所以使用数据滚动. 默认为 100 毫秒.
flattenSpans: boolean
默认情况下, CodeMirror 会将使用相同 class 的两个 span 合并成一个. 通过设置此项为 false 禁用此功能.
addModeClass: boolean
当启用时(默认禁用), 会给每个标记添加额外的表示生成标记的 mode 的以 cm-m 开头的 CSS 样式类. 例如, xml mode 产生的标记, 会添加 cm-m-xml 类.
maxHighlightLength: number
当需要高亮很长的行时, 为了保持响应性能, 当到达某些位置时, 编辑器会直接将其他行设置为纯文本(plain text). 默认为 10000, 可以设置为 Infinity 来关闭此功能.
viewportMargin: integer
指定当前滚动到视图中内容上方和下方要渲染的行数. 这会影响到滚动时要更新的行数. 通常情况下应该使用默认值 10. 可以设置值为 Infinity 始终渲染整个文档. 注意: 这样设置在处理大文档时会影响性能.
vue-codemirror 还提供了一些使用的方法
- scroll
- changes
- beforeChange
- cursorActivity
- keyHandled
- inputRead
- electricInput
- beforeSelectionChange
- viewportChange
- swapDoc
- gutterClick
- gutterContextMenu
- focus
- blur
- refresh
- optionChange
- scrollCursorIntoView
- update
我英语不好就步翻译了, 不过用到的基本就这几个 changes,update,refresh,focus,blur, 其他的看你们的需要而定. 代码编辑后的保存还是要用到 codemirror 的方法, 而使用 codemirror 的方法就是在计算属性使用:
- computed: {
- codemirror() {
- return this.$refs.myCm.codemirror
- }
- },
codemirror 的方法在官网有很详细的解释, 我在这里就列几个常用的
(
(1)getValue(): 获取编辑器文本
(2)setValue(textString): 设置编辑器文本
(3)undo(): 撤销一个编辑器
(4)redo(): 重做一个编辑器
(5)setSelection({line:startLineNumber,ch:start_ch},{line:endLineNumber,ch:end_ch}); 设置一个新的编辑器
(6)getLine(Integer): 获取第 n 行的文本内容
(7)replaceRange(str1,{line,ch},{line,ch},str2): 替换 str1 中一部分代码为 str2
(8)lineCount(): 获取编辑器总行数
(9)replaceSelection(str1,str2): 替换所选内容
到此, 用法已经说完, 开头我提到的三个问题第一第二个已经解决, 第三个解决不了, 应该是 codemirror 内部有自动刷新的程序, 解决页面切换编辑器空白的方法可以在 options 加一个配置 viewportMargin:Infinity 不过这样会影响性能.
总结
来源: https://www.jb51.net/article/149990.htm