编辑器计算框在光标位置插入解决方案:
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