monaco

微软之前有个项目叫做Monaco Workbench,后来这个项目变成了VSCode,而Monaco Editor就是从这个项目中成长出来的一个web编辑器,他们很大一部分的代码(monaco-editor-core)都是共用的,所以monaco和VSCode在编辑代码,交互以及UI上几乎是一摸一样的,有点不同的是,两者的平台不一样,monaco基于浏览器,而VSCode基于electron,所以功能上VSCode更加健全,并且性能比较强大。,[Monaco Editor GitHub地址](https://github.com/Microsoft/monaco-editor)

1.安装monaco

npm install monaco-editor -S
npm install monaco-editor-webpack-plugin -S

vue.config.js中引入monaco-editor-webpack-plugin (monaco是基于本地工作的,即:file://,所以在web端需要替换为http://,引入monaco-editor-plugin即可达到这个效果)

const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
// 自定义webpack配置
  configureWebpack: { 
    output: { 
      library: `${ name}`,
      libraryTarget: 'umd',// 把子应用打包成 umd 库格式
      jsonpFunction: `webpackJsonp_${ name}`,
    },
      plugins: [
          new MonacoWebpackPlugin()
      ]
  },

2.引入并使用monaco

html

<div ref="container">
</div>

js

import * as monaco from 'monaco-editor';
//create [options参数官网地址](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.istandaloneeditorconstructionoptions.html)
this.monacoEditor=monaco.editor.create(this.$refs.container,{ 
            value:`console.log("hello,world")`,
            language:"javascript",
            theme: 'vs-dark', // 编辑器主题:vs, hc-black, or vs-dark,更多选择详见官网 
            editorOptions: { 
	        automaticLayout: true, // 自动布局,
	        autoIndent:true//自动缩进
	      } // 同codes
})

3.监听事件

监听内容被修改:onDidChangeModelContent

this.monacoEditor.onDidChangeModelContent((e) => {  
   console.log(e)   
});

监听blur事件

this.monacoEditor.onDidBlurEditor((e) => {  
     console.log(e); 
});

监听resize

//编辑器随窗口自适应
window.addEventListener('resize',function(){ 
    initEditor();//重新初始化monacoEditor对象
})

4. 部分api

  1. 获取输入内容this.xxx = this.monacoEditor.getValue()
  2. 切换格式动态修改 language方法 : this.monacoEditor.setModelLanguage(this.monacoEditor.getModel(), language);
  3. 动态设置主题颜色 this.monacoEditor.setTheme('xxxxxx')

5.代码格式校验

比如:{name:”zzz”} text 不会提示无法错误,而json提示语法有误(正确应为{“name”:”zzz”})

引入nacos的校验文件,代码如下:
nacos GitHub地址

/* * Copyright 1999-2018 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
import * as yamljs from 'yamljs';
/** * 校验一个配置项 */
function validateProperty(property) { 
const {  length } = property;
let keyLen = 0;
let valueStart = length;
let hasSep = false;
let precedingBackslash = false;
let c;
// 解析 key
while (keyLen < length) { 
c = property[keyLen];
if ((c === '=' || c === ':') && !precedingBackslash) { 
valueStart = keyLen + 1;
hasSep = true;
break;
}
if ((c === ' ' || c === '\t' || c === '\f') && !precedingBackslash) { 
valueStart = keyLen + 1;
break;
}
if (c === '\\') { 
precedingBackslash = !precedingBackslash;
} else { 
precedingBackslash = false;
}
keyLen++;
}
// 解析 value
while (valueStart < length) { 
c = property[valueStart];
if (c !== ' ' && c !== '\t' && c !== '\f') { 
if (!hasSep && (c === '=' || c === ':')) { 
hasSep = true;
} else { 
break;
}
}
valueStart++;
}
return (
validateKeyOrValueForProperty(property, 0, keyLen) &&
validateKeyOrValueForProperty(property, valueStart, length)
);
}
function validateKeyOrValueForProperty(property, start, end) { 
// check null
if (start >= end) { 
return false;
}
let index = 0;
let c;
while (index < property.length) { 
c = property[index++];
if (c !== '\\') { 
continue;
}
c = property[index++];
// check backslash
if (!isPropertyEscape(c)) { 
return false;
}
// check Unicode
if (c === 'u') { 
const unicode = property.slice(index, index + 4).join('');
if (unicode.match(/^[a-f0-9]{4}$/i) === null) { 
return false;
}
index += 4;
}
}
return true;
}
function isPropertyEscape(c = '') { 
return 'abfnrt\\"\'0! #:=u'.includes(c);
}
export default { 
/** * 检测json是否合法 */
validateJson(str) { 
try { 
return !!JSON.parse(str);
} catch (e) { 
return false;
}
},
/** * 检测xml和html是否合法 */
validateXml(str) { 
try { 
if (typeof DOMParser !== 'undefined') { 
const parserObj =
new window.DOMParser()
.parseFromString(str, 'application/xml')
.getElementsByTagName('parsererror') || { };
return parserObj.length === 0;
} else if (typeof window.ActiveXObject !== 'undefined') { 
const xml = new window.ActiveXObject('Microsoft.XMLDOM');
xml.async = 'false';
xml.loadXML(str);
return xml;
}
} catch (e) { 
return false;
}
},
/** * 检测yaml是否合法 */
validateYaml(str) { 
try { 
return yamljs.parse(str);
} catch (e) { 
return false;
}
},
/** * 检测属性是否正确 */
validateProperties(str = '') { 
let isNewLine = true;
let isCommentLine = false;
let isSkipWhiteSpace = true;
let precedingBackslash = false;
let appendedLineBegin = false;
let skipLF = false;
let hasProperty = false;
let property = [];
for (let i = 0; i < str.length; i++) { 
const c = str[i];
if (skipLF) { 
skipLF = false;
if (c === '\n') { 
continue;
}
}
// 跳过行首空白字符
if (isSkipWhiteSpace) { 
if (c === ' ' || c === '\t' || c === '\f') { 
continue;
}
if (!appendedLineBegin && (c === '\r' || c === '\n')) { 
continue;
}
appendedLineBegin = false;
isSkipWhiteSpace = false;
}
// 判断注释行
if (isNewLine) { 
isNewLine = false;
if (c === '#' || c === '!') { 
isCommentLine = true;
continue;
}
}
if (c !== '\n' && c !== '\r') { 
property.push(c);
if (c === '\\') { 
precedingBackslash = !precedingBackslash;
} else { 
precedingBackslash = false;
}
continue;
}
// 跳过注释行
if (isCommentLine || property.length === 0) { 
isNewLine = true;
isCommentLine = false;
isSkipWhiteSpace = true;
property = [];
continue;
}
// 处理转移字符
if (precedingBackslash) { 
property.pop();
precedingBackslash = false;
isSkipWhiteSpace = true;
appendedLineBegin = true;
if (c === '\r') { 
skipLF = true;
}
continue;
}
// 解析出配置项
// 进行校验
if (!validateProperty(property)) { 
return false;
}
hasProperty = true;
property = [];
isNewLine = true;
isSkipWhiteSpace = true;
}
// 校验最后一行
if (property.length > 0 && !isCommentLine) { 
return validateProperty(property);
}
return hasProperty;
},
/** * 根据类型验证类型 */
validate({  content, type }) { 
const validateObj = { 
json: this.validateJson,
xml: this.validateXml,
'text/html': this.validateXml,
html: this.validateXml,
properties: this.validateProperties,
yaml: this.validateYaml
};
if (!validateObj[type]) { 
return true;
}
return validateObj[type](content);
}
};

创建validateContent.js后,在代码内引入

import validateContent from '@/utils/validateContent';
if (validateContent.validate({  content: this.queryFormData.content, type: xxxx })) {  //type xml text json 等
console.log('格式没问题逻辑');
} else { 
console.log('提示格式错误');
}

本文地址:https://blog.csdn.net/qq_36736475/article/details/112562226