美文网首页
Monaco Editor / react-monaco-edi

Monaco Editor / react-monaco-edi

作者: _一九九一_ | 来源:发表于2019-12-18 13:42 被阅读0次

编辑器计算框在光标位置插入解决方案:
https://github.com/microsoft/monaco-editor/issues/584

本文用的是react-monaco-editor
本文的git地址: https://github.com/ysk1991/react-monaco-editor

子组件

import React from 'react'
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api'
import MonacoEditor from 'react-monaco-editor'
import { get_rule_function } from '../../services/api.js'

class DEditor extends React.Component {
  constructor(props) {
    super(props)
    this.monacoEditorRef = React.createRef()
    this.state = {
      setRuleContent: [], // 规则导入的中文 插入到计算框
      tipList: [], // 储存计算框提示语的首字母
      suggestions: [], // 储存提示语
      calculateValue: ''
    }
  }

  componentWillMount() {
    // 拦截判断是否离开当前页面
    window.addEventListener('beforeunload', this.beforeunload)
  }

  componentDidMount() {
    this.setState({
      calculateValue: this.props.calculateValue
    })
  }

  componentWillReceiveProps(nextProps) {
    // nextProps.setRuleContent设置成一个数组 每一次读取数组的最后一个元素 然后在光标的位置插入编辑器
    if (this.state.setRuleContent !== nextProps.setRuleContent) {
      this.setState({
        setRuleContent: nextProps.setRuleContent
      })
      const editor = this.monacoEditorRef.current.editor
      const p = editor.getPosition()
      editor.executeEdits('',
        [
          {
            range: new monaco.Range(p.lineNumber,
              p.column,
              p.lineNumber,
              p.column),
            text: nextProps.setRuleContent[nextProps.setRuleContent.length - 1]
          }
        ]
      )
    }
    // 编辑框的值
    if (this.state.calculateValue !== nextProps.calculateValue) {
      this.setState({
        calculateValue: nextProps.calculateValue
      })
    }
  }

  beforeunload() {
    // 如果是刷新页面 清空sessionStorage
    sessionStorage.removeItem('isLoadDEditor')
  }

  // 自定义按键提示的数据请求
  requestList = async() => {
    const list = []
    const tipList = [':']
    const res = await get_rule_function()
    if (res.data.responseCode) return
    const responseData = res.data.responseData
    responseData.map(item => {
      const obj = {}
      obj.label = item.content
      obj.insertText = item.content
      obj.detail = item.symbolName
      list.push(obj)
      tipList.push(item.content.substring(0, 1))
      return null
    })
    this.setState({
      suggestions: list,
      tipList: tipList
    })
  }

  onBlur = () => {
    const { calculateValue } = this.state
    this.props.value(calculateValue)
    if (calculateValue) {
      this.props.isEditorErrFn(false)
    }
  }

  onChangeHandle = (value, e) => {
    this.setState({
      calculateValue: value
    })
  }

  editorDidMountHandle = async(editor, monaco) => {
    // 执行过就不再执行 当页面关闭就重新记录 因为多次执行了这个方法导致重复数据
    const isLoadDEditor = sessionStorage.getItem('isLoadDEditor')
    if (isLoadDEditor !== '1') {
      sessionStorage.setItem('isLoadDEditor', '1')
      await this.requestList()
      const { suggestions, tipList } = this.state
      if (suggestions.length) {
        monaco.languages.registerCompletionItemProvider('plaintext', {
          provideCompletionItems() {
            // console.log('这个地方,每一次路由变动,就会多执行一次,导致我的按键提示重复展示')
            return {
              suggestions: suggestions.map(item => ({ ...item, kind: monaco.languages.CompletionItemKind.Variable }))
            }
          },
          triggerCharacters: tipList
        })
      }
      this.timeouter = setTimeout(() => {
        editor.getAction('editor.action.formatDocument').run()
      }, 300)
    }
  }

  options = {
    selectOnLineNumbers: true,
    renderSideBySide: false
  }

  render() {
    return (
      <div onBlur={this.onBlur}>
        <MonacoEditor
          ref={this.monacoEditorRef}
          width='900'
          height='200'
          language='plaintext'
          theme='vs-dark'
          value={this.state.calculateValue}
          options={this.options}
          onChange={this.onChangeHandle}
          editorDidMount={this.editorDidMountHandle}
        />
      </div>
    )
  }
}

export default DEditor

父组件

import React from 'react'
import Loadable from 'react-loadable'
import { MyLoadingComponent } from '../utils/utils'

const Editor = Loadable({
  loader: () => import('../components/Editor'),
  loading: MyLoadingComponent
})

class Calculate extends React.Component {
  constructor() {
    super()
    this.editorRef = React.createRef()
  }

  state = {
    setRuleContent: [], // 规则导入的中文 插入到计算框
    componentContentCn: '', // 计算框的内容
    isEditorErr: false // 控制计算框的报错
  }

  // 将计算框的值传递出去
  getValue = (componentContentCn) => {
    this.setState({
      componentContentCn
    })
    this.props.value(componentContentCn)
  }

  render() {
    return (
      <Editor
        ref={this.editorRef}
        value={this.getValue}
        calculateValue={this.state.componentContentCn}
        setRuleContent={this.state.setRuleContent}
      ></Editor>
    )
  }
}

export default Calculate

相关文章

网友评论

      本文标题:Monaco Editor / react-monaco-edi

      本文链接:https://www.haomeiwen.com/subject/fqqunctx.html