前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【CodeMirror】:代码编辑器

【CodeMirror】:代码编辑器

作者头像
WEBJ2EE
发布2021-01-28 15:47:53
2.8K0
发布2021-01-28 15:47:53
举报
文章被收录于专栏:WebJ2EEWebJ2EE
代码语言:javascript
复制
目录
1. CodeMirror 是什么?能做什么?
2. CodeMirror 使用特点?项目解构?
3. CodeMirror 常用配置?
4. React 中如何使用 CodeMirror?
5. CodeMirror 的 lint 特性是靠什么实现的?
6. 综合示例

1. CodeMirror 是什么?能做什么?

CodeMirror is a versatile text editor implemented in JavaScript for the browser.

  • CodeMirror 最广泛的应用是代码高亮,内置 n 种语言支持,常见的有:
    • css
    • javascript
    • jsx
    • sql
    • vue
  • CodeMirror 同样支持内置 n 种主题支持,常用的有:
    • eclipse
    • darcula
    • idea
  • CodeMirror 通过扩展机制,可以支持:
    • 缩进控制(indentUnit、tabSize)
    • 行号展示(lineNumbers)
    • 括号、标签匹配(matchBrackets、matchTags)
    • 括号、标签自动闭合(autoCloseBrackets、autoCloseTags)
    • 折叠代码块(foldGutter)
    • 代码校验(lint)

2. CodeMirror 使用特点?项目解构?

通常使用 CodeMirror 的地方,都会看到一大堆模块导入 import 语句,例如:

CodeMirror 的模块化特征非常强,基本上所有特性,都需要独立引入:

  • 内核:codemirror/lib
  • 主题:codemirror/theme
  • 语言支持:codemirror/mode
  • 特性扩展:codemirror/addon

3. CodeMirror 常用配置?

CodeMirror 有 n 多配置,常用的有:

4. React 中如何使用 CodeMirror?

React 环境下可以使用 CodeMirror 的包装项目:react-codemirror2

安装:

代码语言:javascript
复制
npm install react-codemirror2 codemirror --save

受控 & 非受控:

  • react-codemirror2 ships with the notion of an uncontrolled and controlled component.
    • UnControlled consists of a simple wrapper largely powered by the inner workings of codemirror itself.
    • Controlled will demand state management from the user, preventing codemirror changes unless properly handled via value.
代码语言:javascript
复制
import {UnControlled as CodeMirror} from 'react-codemirror2'

<CodeMirror
  value='<h1>I ♥ react-codemirror2</h1>'
  options={{
    mode: 'xml',
    theme: 'material',
    lineNumbers: true
  }}
  onChange={(editor, data, value) => {
  }}
/>
代码语言:javascript
复制
import {Controlled as CodeMirror} from 'react-codemirror2'

<CodeMirror
  value={this.state.value}
  options={options}
  onBeforeChange={(editor, data, value) => {
    this.setState({value});
  }}
  onChange={(editor, data, value) => {
  }}
/>

注意:

  • codemirror comes as a peer dependency, meaning you'll need to require it in your project in addition to react-codemirror2. This prevents any versioning conflicts that would arise if codemirror came as a dependency through this wrapper. It's been observed that version mismatches can cause difficult to trace issues such as syntax highlighting disappearing without any explicit errors/warnings
  • Since codemirror ships mostly unconfigured, the user is left with the responsibility for requiring any additional resources should they be necessary. This is often the case when specifying certain language modes and themes.

5. CodeMirror 的 lint 特性是靠什么实现的?

vue-element-admin 中使用 CodeMirror 实现了一个带校验功能的 JsonEditor。

通过查看 codemirror/addon/lint/json-lint.js 的源码得知,json-lint.js 是在内部直接检测、使用全局(window)中注册的 jsonlint 对象,完成校验。

CodeMirror 的其他格式 lint,也采用了类似原理:

  • json-lint:window.jsonlint
  • css-lint:window.CSSLint
  • html-lint:window.HTMLHint
  • javascript-lint:window.JSHINT

6. 综合示例

代码语言:javascript
复制
import React from "react";
import { Controlled as CodeMirror } from "react-codemirror2";

import "codemirror/lib/codemirror.css";

import "codemirror/theme/darcula.css";
import "codemirror/mode/javascript/javascript";

import "codemirror/addon/edit/closebrackets";
import "codemirror/addon/edit/closetag";
import "codemirror/addon/edit/matchbrackets";
import "codemirror/addon/edit/matchtags";

import "codemirror/addon/fold/foldcode";
import "codemirror/addon/fold/foldgutter";
import "codemirror/addon/fold/brace-fold";
import "codemirror/addon/fold/foldgutter.css";

import "codemirror/addon/lint/lint"
import "codemirror/addon/lint/javascript-lint"
import "codemirror/addon/lint/lint.css"
// @ts-ignore
import jshint from 'jshint'
// @ts-ignore
window.JSHINT = jshint.JSHINT;

interface JavascriptEditorProps {
  value: string;
  onChange: (value: string) => void;
}

export default function JavascriptEditor(props: JavascriptEditorProps) {
  const { value, onChange } = props;

  return (
    <CodeMirror
      value={value}
      options={{
        foldGutter: true,
        gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "CodeMirror-lint-markers"],
        mode: { name: 'javascript', json: true },
        lineNumbers: true,
        lineWrapping: false,
        theme: "darcula",
        autoCloseTags: true,
        autoCloseBrackets: true,
        lint: true,
        matchBrackets: true,
        matchTags: true,
        indentUnit: 2,
        tabSize: 2,
      }}
      onBeforeChange={(editor, data, value) => {
        if (onChange) {
          onChange(value);
        }
      }}
      onChange={(editor, data, value) => { }}
    />
  );
}

参考:

CodeMirror 官网: http://codemirror.net/ CodeMirror 配置手册: https://codemirror.net/doc/manual.html react-codemirror2: https://github.com/scniro/react-codemirror2 vue-element-admin 的 JsonEditor 组件: https://github.com/PanJiaChen/vue-element-admin/blob/master/src/components/JsonEditor/index.vue

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-01-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 WebJ2EE 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档