基于Code Mirror的在线Web 编辑器

pacel构建

  • 好坑这个pacel,贴个效果图吧,但是构建的速度是真的快


    pacel构建的编辑器.png

webpack + vue + CodeMirror 构建

  • 需要的依赖包包"vue-codemirror": "^4.0.5",
  • html页面的代码
<template>
  <codemirror class="CodeMirror" //用于写css覆盖其样式
              ref="myCm"
              :value="code" //编辑器内容
              :options="cmOptions"//编辑器配置
              @ready="onCmReady"
              @focus="onCmFocus"//focus事件
              @input="onCmCodeChange"//输入时触发
              >
    
  </codemirror>
</template>
  • js实现
<script>
// 我这里引入的是SQL语言文件
import 'codemirror/mode/sql/sql.js'
// 编辑的主题文件
import 'codemirror/theme/base16-light.css'
//编辑器代码高亮css文件
import 'codemirror/addon/hint/show-hint.css'
//代码折叠文件
require('codemirror/addon/fold/foldcode.js')
require('codemirror/addon/fold/foldgutter.js')
require('codemirror/addon/edit/matchbrackets.js')
require('codemirror/addon/fold/brace-fold.js')
//选中行高亮文件
require('codemirror/addon/selection/active-line.js') 
//缩进文件
require('codemirror/addon/fold/indent-fold.js')
//代码只能提示
require('codemirror/addon/hint/show-hint.js')
require('codemirror/addon/hint/sql-hint.js')
//addon文件夹放的是Code Mirror的功能插件
require('codemirror/addon/fold/comment-fold.js')
export default {
  data () {
    return {
      code: `-- 按ctrl唤起智能提示
      SELECT * FROM`,//初始默认编辑器内容
      cmOptions: {
        // 编辑器设置
        tabSize: 4,//tab大小
        mode: 'text/x-mysql',//编辑器模式支持文件
        theme: 'base16-light',//编辑器主题
        lineNumbers: true,//编辑器行号
        line: true,
        dragDrop: true,//拖拽
        lineWrapping: true, //代码折叠
        matchBrackets: true,  //括号匹配
        // autofocus: true,//自动聚焦
        indentWithTabs: true,//首行缩进
        smartIndent: true,
        extraKeys:{"Ctrl":"autocomplete"},//ctrl唤起智能提示
        // more codemirror options, 更多 codemirror 的高级配置...
        hintOptions: {tables: {
          users: ["name", "score", "birthDate"],
          countries: ["name", "population", "size"]
        }},
      }
    }
  },
  methods: {
    onCmReady(cm) {
      console.log('the editor is readied!', cm)
    },
    onCmFocus(cm) {
      console.log('the editor is focus!', cm)
    },
    onCmCodeChange(newCode) {
      console.log('this is new code', newCode)
      this.code = newCode
    }
  },
  computed: {
    codemirror() {
     console.log(this.$refs.myCm.codemirror.lineCount()) 
      //这里可以写方法,比如下面的设置内容
     this.$refs.myCm.codemirror.setValue(this.code + ' '+ 'aaaaaaaaaaaaaaa')
      return this.$refs.myCm.codemirror
    }
  },
  mounted() {
    console.log('this is current codemirror object', this.codemirror)
    // you can use this.codemirror to do something...
  }
}
</script>
  • 效果如下,一样的代码跟pacel最后的页面不一样😂😂


    webpack+vue构建的编辑器.png

常用配置

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始终渲染整个文档。注意:这样设置在处理大文档时会影响性能。

编辑器事件

  • 编辑器实例会触发以下这些事件。其中的instance参数总是指向编辑器本身。

  • change: (instance: CodeMirror, changeObj: object)
    每当编辑器内容发生变化时触发。参数changeObj是一个{from, to, text, removed, origin}对象,包含内容变化的信息。其中from和to是内容改变发生的起止位置(改变发生之前),举个例子,如果改变始于第19行之初,则from为{ch:0, line:18}。text替换起止位置之间内容的文字,按行分割开,组成数组。removed则是被替换掉的内容。这个事件会在operation临结束前,在DOM更新之前触发。

  • changes: (instance: CodeMirror, changes: array:)
    类似于change事件,不过是在每次operation后,将改变一次过打包成数组传出来。而展现这些改变,又将出发一次新的operation。

  • beforeChange: (instance: CodeMirror, changeObj:object)
    这个事件在内容改变生效前触发,它的handler可以此来修改或取消这次改变。其中的changeObj对象有from, to, text属性。它还包含一个cancel()方法,用于取消这次改变,而且如果这次改变不是来自撤销(undo)与重做(redo)操作的画,它还会有一个update(from, to, text)方法,用来修改这次改变。update方法的3个参数都不是必填的,可以不传入,以直接使用原先的值。注意:你不该在beforeChange的handler中做任务会导致document或其视觉表现的操作。

  • cursorActivity: (instance: CodeMirror)
    每当光标或内容选择移动时出发,因此编辑器中任务内容的改变也会出发。

  • keyHandled: (instance: CodeMirror, name: string, event: Event)
    每当一个快捷键被通过key map handled时触发。name是被handled的键(例如”ctrl-x”或者“‘q’”),而event则是DOM的keydown或keypress事件。

  • inputRead: (instance: CodeMirror, changeObj: object)
    每当被因此对textarea中有新的输入被读取到时触发(可能是来自键盘输入或粘贴)。

  • electricInput: (instance: CodeMirror, line: integer)
    当输入的文字匹配mode的electric模式时触发,这会导致该行的缩进发生改变。

  • beforeSelectionChange: (instance: CodeMirror, obj: {range, origin, update})

  • viewportChange: (instance: CodeMirror, from: number, to: number)
    当可视区发生变化时触发(这可能是由于滚动、编辑内容等原因造成)。其参数from和to给出了可视区新的起始位置。

  • swapDoc: (instance: CodeMirror, oldDoc: Doc)
    当编辑器的document被使用swapDoc方法更换掉时触发。

  • gutterClick: (instance: CodeMirror, line: integer, gutter: string, clickEvent: Event)
    每当编辑器的gutter被点击时触发。其参数分别为编辑器实例;为被点击的行数,从0开始计数;+ gutter的CSS class名;mousedown的原始事件。

  • gutterContextMenu: (instance: CodeMirror, line: integer, gutter: string, contextMenu: Event)
    每当编辑器的gutter收到contextmenu事件时触发。与gutterClick不同的是,最后一个参数是contextmenu事件。你可以preventDefault这个事件,这会通知CodeMirror不再进一步handle。

  • focus: (instace: CodeMirror)
    当编辑器获得焦点时触发。

  • blur: (instance: CodeMirror)
    当编辑器失去焦点时触发。

  • scroll: (instance: CodeMirror)
    当编辑器滚动时触发。

  • scrollCursorIntoView (instance: CodeMirror, event: Event)

  • update: (instance: CodeMirror)
    每当CodeMirror更新它的DOM展示时触发。

  • renderLine (instance: CodeMirror, line: LineHandle, element: Element)
    每当一行需要被绘制(重绘)成DOM时触发。它触发在DOM元素建立好之后,但在加入document之前。handler可以改动该元素的样式,或是为其添加event handlers,但不该尝试改变编辑器的状态。

  • mousedown, dbclick, touchstart, contextmenu, keydown, keypress, keyup, cut, copy ,paste, dragstart, dragenter, dragover, dragleave, drop: (instance: CodeMirror, event: Event)
    当CodeMirrorhandle这些DOm事件时触发。你可以preventDefault这些事件,也可以把它们的codemirrorIgnore属性设为真值,以告知CodeMirror不要再继续handle。
    文档对象(Document objects, CodeMirror.Doc的实例)

  • change: (doc: CodeMirror.Doc, changeObj: object)
    每当document发生改变时触发。参数changeObj类似于编辑器change事件的changeObj。

  • beforeChange: (doc: CodeMirror.Doc, change: object) 参见编辑器的同名事件。

  • cursorActivity: (doc: CodeMirror.Doc) 每当document中的光标和选区变化时触发。

  • beforeSelectionChange: (doc: CodeMirror.Doc, selection: {head, anchor}) 参见编辑器的同名事件。

  • Line handles as returned by, for example, getLineHandle(可以理解为行对象)

  • delete: ()当行对象被删除时触发。

  • change: (line: LineHandle, changeObj: object) 当行对象中的内容发生改变(但这一行并没有被完全删除)时触发。changeObj跟编辑器对象的同名事件一样。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,175评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,674评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,151评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,597评论 1 269
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,505评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,969评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,455评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,118评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,227评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,213评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,214评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,928评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,512评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,616评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,848评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,228评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,772评论 2 339

推荐阅读更多精彩内容

  • 今天上午去房地局继续咨询写字楼的税费疑问点,反复核算、提问、核算再提问,找相关部门最终落实,其实很简单,重在专注...
    邓慧娟阅读 155评论 1 0
  • 今天是周日,这是每个人都期盼的日子,甚至大家都想每天都是周日。不用上班,可以做自己喜欢的事情。 早上,我去铁路走走...
    妈妈随笔阅读 155评论 0 0
  • 白色戒圈套住的 不是婚姻的坚不可摧 不是感情的我侬你侬 ‘它’只是一个名叫戒指的圈 材质可贱可贵 模样可爱可怖 时...
    郭大胆LYX阅读 202评论 6 5
  • 这句话好像很多人说过,但是我今天有了一种新的感受。 就是:你的生活态度,会改变你身边的人。而你身边的人,会改变你...
    兵_aeb1阅读 1,142评论 0 3