React中使用react-ace實現(xiàn)代碼編輯框自動提詞功能

簡介

Ace是一個用JavaScript編寫的可嵌入代碼編輯器憎茂。它與Sublime,Vim和TextMate等本機編輯器的功能和性能相匹配。它可以輕松地嵌入任何網(wǎng)頁和JavaScript應用程序中筋帖,React-Ace是Ace 的react 封裝版本迅耘,使用簡單贱枣,方便配合form表單使用。

安裝

npm install react-ace ace-builds
或者
yarn add react-ace ace-builds

業(yè)務(wù)背景

需要在前端頁面實現(xiàn)sql和javascript配置颤专,后臺解析纽哥,計算結(jié)果,(結(jié)算引擎)

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 設(shè)置值
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 顯示的最小行數(shù)
maxLines Number 顯示的最大行數(shù)
enableBasicAutocompletion false Boolean 啟用基本自動補全
enableLiveAutocompletion false Boolean 啟用實時自動補全
enableSnippets false Boolean 啟用摘要
tabSize 4 Number tab空格值
debounceChangePeriod null Number onChange事件的抖動延遲時間
onLoad Function 在編輯器加載時調(diào)用栖秕。第一個參數(shù)是編輯器的實例
onBeforeLoad Function 在編輯器加載之前調(diào)用春塌。第一個參數(shù)是的實例ace
onChange Function 發(fā)生在文檔更改上,它具有2個參數(shù)簇捍,每個編輯器的值和事件
onCopy Function 由編輯器copy事件觸發(fā)只壳,并將文本作為參數(shù)傳遞
onPaste Function 由編輯器paste事件觸發(fā),并將文本作為參數(shù)傳遞
onSelectionChange Function 由編輯器selectionChange事件觸發(fā)暑塑,并且將Selection作為第一個參數(shù)傳遞吼句,并將事件作為第二個參數(shù)傳遞
onCursorChange Function 由編輯器changeCursor事件觸發(fā),并且將Selection作為第一個參數(shù)傳遞事格,并將事件作為第二個參數(shù)傳遞
onFocus Function 由編輯器focus事件觸發(fā)
onBlur Function 由編輯器blur事件觸發(fā)
onInput Function 由編輯器input事件觸發(fā)
onScroll Function 由編輯器scroll事件觸發(fā)
editorProps Object 可直接應用于Ace編輯器實例的屬性
setOptions Object 直接應用于Ace編輯器實例的選項
keyboardHandler String 對應于要設(shè)置的綁定模式(例如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選項

mode.png

編輯器theme選項

theme.png

使用注意項

首先在全局或者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}
     // 設(shè)置編輯器格式化和代碼提示 
      setOptions={{
        useWorker: false,
        enableBasicAutocompletion: true,
        enableLiveAutocompletion: true,
        // 自動提詞此項必須設(shè)置為true
        enableSnippets: true,
        showLineNumbers: false,
        tabSize: 2,
      }}
    />

如果要自定義提詞(此處有坑6А)

  const complete = (editor: any) => {
    editor.completers = [
      // 自己的代碼提示
      {
        getCompletions: function (
          editor: any,
          session: any,
          pos: any,
          prefix: any,
          callback: any
        ) {
          callback(null, completers)
        },
      },
      // 編輯器的代碼提示
      // ...editor.completers,
    ]
  }

此時如果想要動態(tài)改變提示詞數(shù)組桨吊,上面代碼是做不到的,現(xiàn)在是全量提示磕昼,即在onload加載完之后調(diào)用complete函數(shù)時延都,編輯器的代碼提示已經(jīng)被加載了,如果想要動態(tài)加載代碼提示棠耕,需要強制渲染編輯器余佛,react中我這樣搞的

 useEffect(() => {
    // !動態(tài)改變編輯器的代碼提示,必須重新設(shè)置
    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'
// 編輯器需要自定義時的數(shù)據(jù)結(jié)構(gòu)
// 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(() => {
    // !動態(tài)改變編輯器的代碼提示窍荧,必須重新設(shè)置
    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

最終實現(xiàn)效果如下:


image.png

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'
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蕊退,一起剝皮案震驚了整個濱河市郊楣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌瓤荔,老刑警劉巖净蚤,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異输硝,居然都是意外死亡今瀑,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門点把,熙熙樓的掌柜王于貴愁眉苦臉地迎上來橘荠,“玉大人,你說我怎么就攤上這事郎逃「缤” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵衣厘,是天一觀的道長如蚜。 經(jīng)常有香客問我,道長影暴,這世上最難降的妖魔是什么错邦? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮型宙,結(jié)果婚禮上撬呢,老公的妹妹穿的比我還像新娘。我一直安慰自己妆兑,他們只是感情好魂拦,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布毛仪。 她就那樣靜靜地躺著,像睡著了一般芯勘。 火紅的嫁衣襯著肌膚如雪箱靴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天荷愕,我揣著相機與錄音衡怀,去河邊找鬼。 笑死安疗,一個胖子當著我的面吹牛抛杨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播荐类,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼怖现,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了玉罐?” 一聲冷哼從身側(cè)響起屈嗤,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吊输,沒想到半個月后恢共,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡璧亚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了脂信。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片癣蟋。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖狰闪,靈堂內(nèi)的尸體忽然破棺而出疯搅,到底是詐尸還是另有隱情,我是刑警寧澤埋泵,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布幔欧,位于F島的核電站,受9級特大地震影響丽声,放射性物質(zhì)發(fā)生泄漏礁蔗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一雁社、第九天 我趴在偏房一處隱蔽的房頂上張望浴井。 院中可真熱鬧,春花似錦霉撵、人聲如沸磺浙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撕氧。三九已至瘤缩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伦泥,已是汗流浹背剥啤。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留奄喂,地道東北人铐殃。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像跨新,于是被迫代替她去往敵國和親富腊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容