編輯器計(jì)算框在光標(biāo)位置插入解決方案:
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: [], // 規(guī)則導(dǎo)入的中文 插入到計(jì)算框
tipList: [], // 儲存計(jì)算框提示語的首字母
suggestions: [], // 儲存提示語
calculateValue: ''
}
}
componentWillMount() {
// 攔截判斷是否離開當(dāng)前頁面
window.addEventListener('beforeunload', this.beforeunload)
}
componentDidMount() {
this.setState({
calculateValue: this.props.calculateValue
})
}
componentWillReceiveProps(nextProps) {
// nextProps.setRuleContent設(shè)置成一個(gè)數(shù)組 每一次讀取數(shù)組的最后一個(gè)元素 然后在光標(biāo)的位置插入編輯器
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')
}
// 自定義按鍵提示的數(shù)據(jù)請求
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) => {
// 執(zhí)行過就不再執(zhí)行 當(dāng)頁面關(guān)閉就重新記錄 因?yàn)槎啻螆?zhí)行了這個(gè)方法導(dǎo)致重復(fù)數(shù)據(jù)
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('這個(gè)地方互捌,每一次路由變動膘掰,就會多執(zhí)行一次,導(dǎo)致我的按鍵提示重復(fù)展示')
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: [], // 規(guī)則導(dǎo)入的中文 插入到計(jì)算框
componentContentCn: '', // 計(jì)算框的內(nèi)容
isEditorErr: false // 控制計(jì)算框的報(bào)錯
}
// 將計(jì)算框的值傳遞出去
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