简介
Ace是一个用JavaScript编写的可嵌入代码编辑器。它与Sublime,Vim和TextMate等本机编辑器的功能和性能相匹配。它可以轻松地嵌入任何网页和JavaScript应用程序中,React-Ace是Ace 的react 封装版本,使用简单,方便配合form表单使用。
安装
npm install react-ace ace-builds
或者
yarn add react-ace ace-builds
业务背景
需要在前端页面实现sql和javascript配置,后台解析,计算结果,(结算引擎)
react-ace 编辑器属性
Prop | Default | Type | Description |
---|---|---|---|
name | 'ace-editor' | String | 用于编辑器的唯一ID |
mode | '' | String | 解析和代码突出显示的语言 |
splits | 2 | Number | 视图拆分 |
orientation | 'beside' | String | 拆分的方向在旁边还是在下面 |
theme | '' | String | 使用的主题 |
value | '' | Array of Strings | 设置值 |
defaultValue | '' | Array of Strings | 每个编辑器的默认值 |
height | '500px' | String | 高度的CSS值 |
width | '500px' | String | 宽度的CSS值 |
className | String | 自定义类名 | |
fontSize | 12 | Number | 字体大小的像素值 |
showGutter | true | Boolean | 显示槽 |
showPrintMargin | true | Boolean | 显示打印边距 |
highlightActiveLine | true | Boolean | 突出显示活动行 |
focus | false | Boolean | 是否聚焦 |
cursorStart | 1 | Number | 光标的位置 |
wrapEnabled | false | Boolean | 包装线 |
readOnly | false | Boolean | 使编辑器为只读 |
minLines | Number | 显示的最小行数 | |
maxLines | Number | 显示的最大行数 | |
enableBasicAutocompletion | false | Boolean | 启用基本自动补全 |
enableLiveAutocompletion | false | Boolean | 启用实时自动补全 |
enableSnippets | false | Boolean | 启用摘要 |
tabSize | 4 | Number | tab空格值 |
debounceChangePeriod | null | Number | onChange事件的抖动延迟时间 |
onLoad | Function | 在编辑器加载时调用。第一个参数是编辑器的实例 | |
onBeforeLoad | Function | 在编辑器加载之前调用。第一个参数是的实例ace | |
onChange | Function | 发生在文档更改上,它具有2个参数,每个编辑器的值和事件 | |
onCopy | Function | 由编辑器copy事件触发,并将文本作为参数传递 | |
onPaste | Function | 由编辑器paste事件触发,并将文本作为参数传递 | |
onSelectionChange | Function | 由编辑器selectionChange事件触发,并且将Selection作为第一个参数传递,并将事件作为第二个参数传递 | |
onCursorChange | Function | 由编辑器changeCursor事件触发,并且将Selection作为第一个参数传递,并将事件作为第二个参数传递 | |
onFocus | Function | 由编辑器focus事件触发 | |
onBlur | Function | 由编辑器blur事件触发 | |
onInput | Function | 由编辑器input事件触发 | |
onScroll | Function | 由编辑器scroll事件触发 | |
editorProps | Object | 可直接应用于Ace编辑器实例的属性 | |
setOptions | Object | 直接应用于Ace编辑器实例的选项 | |
keyboardHandler | String | 对应于要设置的绑定模式(例如vim或emacs) | |
commands | Array | 新命令添加到编辑器 | |
annotations | Array of Arrays | 要在编辑器中[{ row: 0, column: 2, type: ‘error’, text: ‘Some error.’}]显示的注释,即在装订线中显示 | |
markers | Array of Arrays | 要在编辑器中显示的标记,即[{ startRow: 0, startCol: 2, endRow: 1, endCol: 20, className: ‘error-marker’, type: ‘background’ }] | |
style | Object | 驼峰属性 |
编辑器mode选项
编辑器theme选项
使用注意项
首先在全局或者react组件中引入mode和theme
// 引入对应的mode
import 'ace-builds/src-noconflict/mode-javascript'
// 引入对应的theme
import 'ace-builds/src-noconflict/theme-xcode'
// 如果要有代码提示,下面这句话必须引入!!!
import 'ace-builds/src-noconflict/ext-language_tools'
在render中使用
<AceEditor
ref={editorInstance}
placeholder={placeholder}
mode="javascript"
theme="xcode"
name="UNIQUE_ID_OF_DIV"
fontSize={14}
defaultValue={defaultValue}
editorProps={{
$blockScrolling: false,
}}
onChange={onChange}
onPaste={onChange}
onLoad={complete}
showPrintMargin={false}
showGutter={true}
highlightActiveLine={true}
// 设置编辑器格式化和代码提示
setOptions={{
useWorker: false,
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
// 自动提词此项必须设置为true
enableSnippets: true,
showLineNumbers: false,
tabSize: 2,
}}
/>
如果要自定义提词(此处有坑!)
const complete = (editor: any) => {
editor.completers = [
// 自己的代码提示
{
getCompletions: function (
editor: any,
session: any,
pos: any,
prefix: any,
callback: any
) {
callback(null, completers)
},
},
// 编辑器的代码提示
// ...editor.completers,
]
}
此时如果想要动态改变提示词数组,上面代码是做不到的,现在是全量提示,即在onload加载完之后调用complete函数时,编辑器的代码提示已经被加载了,如果想要动态加载代码提示,需要强制渲染编辑器,react中我这样搞的
useEffect(() => {
// !动态改变编辑器的代码提示,必须重新设置
complete(editorInstance.current.editor)
}, [completers])
全部代码如下:
import React, { useEffect, useRef } from 'react'
import AceEditor from 'react-ace'
import 'ace-builds/src-noconflict/mode-javascript'
import 'ace-builds/src-noconflict/theme-xcode'
import 'ace-builds/src-noconflict/ext-language_tools'
import 'ace-builds/webpack-resolver'
// 编辑器需要自定义时的数据结构
// const completers = [
// {
// // name: 'name',
// value: 'price',
// // score: 100,
// meta: '变量类-单价',
// },
// {
// // name: 'name',
// value: 'Waybill.price',
// // score: 100,
// meta: '变量类-单价',
// },
// ]
const SqlEditor = (props: any) => {
const editorInstance = useRef<any>() // 获取编辑器实例
const { placeholder, defaultValue, onChange, completers } = props
const complete = (editor: any) => {
editor.completers = [
// 自己的代码提示
{
getCompletions: function (
editor: any,
session: any,
pos: any,
prefix: any,
callback: any
) {
callback(null, completers)
},
},
// 编辑器的代码提示
// ...editor.completers,
]
}
useEffect(() => {
// !动态改变编辑器的代码提示,必须重新设置
complete(editorInstance.current.editor)
}, [completers])
return (
<AceEditor
ref={editorInstance}
placeholder={placeholder}
mode="javascript"
theme="xcode"
name="UNIQUE_ID_OF_DIV"
fontSize={14}
defaultValue={defaultValue}
editorProps={{
$blockScrolling: false,
}}
onChange={onChange}
onPaste={onChange}
onLoad={complete}
showPrintMargin={false}
showGutter={true}
highlightActiveLine={true}
setOptions={{
useWorker: false,
enableBasicAutocompletion: true,
enableLiveAutocompletion: true,
enableSnippets: true,
showLineNumbers: false,
tabSize: 2,
}}
/>
)
}
export default SqlEditor
最终实现效果如下:
bug处理
useWorker的时候,会报错Unable to infer path to ace from script src, use ace.config.set('basePath', 'path') to enable dynamic loading of modes and themes or with webpack use ace/webpack-resolver, 需要引入:
import 'ace-builds/webpack-resolver'