百花齐放,终归还是要统一
前序:
碎碎念:
- 此文个人笔记,官网文档搬运
- monaco 版本:0.30.0
- monaco-editor-webpack-plugin 版本:6.0.0 (仅适合模块引入方式)
- vue 版本:2.6.11
一:步骤:
2 —— 引入开发组件【monaco】
1 —— 模块引入monaco(非推荐模式,编译慢折磨人):
npm install monaco-editor
npm install monaco-editor-webpack-plugin --dev
1.1 —— 编辑vue.config.js:
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
module.exports = {
// 省略N多个设置,请勿直接复制使用,仅展示Monaco需要的以及基本结构
configureWebpack: {
plugins: [
new MonacoWebpackPlugin({
languages: ['javascript', 'yaml', 'json', 'xml']
})
],
}
}
1.2 —— 创建editor组件:
<template>
<div ref="CodeEditor"></div>
</template>
<script>
import * as monaco from 'monaco-editor'
export default {
props: {
editable: { type: Boolean, default: true },
language: { type: String, default: 'plaintext' },
value: { type: String, required: true, default: '' },
},
data() {
return {
codeEditor: null,
}
},
mounted() {
this.updateEditor(this.value)
},
methods: {
updateEditor(content) {
if (!this.codeEditor) {
monaco.editor.defineTheme('myTheme', {
base: 'vs',
inherit: true,
rules: [{ background: 'EDF9FA' }],
colors: {
'editor.foreground': '#000000',
'editor.background': '#EDF9FA',
'editorCursor.foreground': '#8B0000',
'editor.lineHighlightBackground': '#0000FF20',
'editorLineNumber.foreground': '#008800',
'editor.selectionBackground': '#88000030',
'editor.inactiveSelectionBackground': '#88000015',
},
})
monaco.editor.setTheme('myTheme')
this.codeEditor = monaco.editor.create(this.$refs.CodeEditor, {
value: '',
language: this.language,
lineNumbers: 'off',
roundedSelection: false,
scrollBeyondLastLine: false,
readOnly: !this.editable,
theme: 'vs-dark',
automaticLayout: true,
wordWrap: 'wordWrapColumn',
wordWrapColumn: 40,
// Set this to false to not auto word wrap minified files
wordWrapMinified: true,
// try "same", "indent" or "none"
wrappingIndent: 'indent',
scrollbar: {
// Subtle shadows to the left & top. Defaults to true.
useShadows: false,
// Render vertical arrows. Defaults to false.
verticalHasArrows: false,
// Render horizontal arrows. Defaults to false.
horizontalHasArrows: false,
// Render vertical scrollbar.
// Accepted values: 'auto', 'visible', 'hidden'.
// Defaults to 'auto'
vertical: 'auto',
// Render horizontal scrollbar.
// Accepted values: 'auto', 'visible', 'hidden'.
// Defaults to 'auto'
horizontal: 'auto',
verticalScrollbarSize: 10,
horizontalScrollbarSize: 10,
arrowSize: 10,
},
//小地图
minimap: {
enabled: false,
},
})
this.codeEditor.onDidChangeModelContent(() => {
this.$emit('input', this.codeEditor.getValue())
})
}
if (content != this.codeEditor.getValue())
this.codeEditor.setValue(content)
this.codeEditor.updateOptions({
readOnly: !this.editable,
})
},
},
watch: {
value: function (val) {
this.updateEditor(val)
},
},
beforeDestroy() {
this.codeEditor.dispose()
},
}
</script>
1.3 —— 组件调用:
<template>
<CodeEditor
v-model="content"
:language="language"
/>
</template>
<script>
import CodeEditor from '@/components/CodeEditor.vue'
export default {
components: { CodeEditor },
data() {
return {
content: '潇风剑易水',
language: '',
}
},
}
</script>
2 —— 静态引入monaco(首选模式):
2.1 —— 创建editor组件:
<template>
<div style="width: 100%; height: 300px" ref="editor"></div>
</template>
<script>
export default {
props: {
editable: { type: Boolean, default: true },
language: { type: String, default: "plaintext" },
value: { type: String, default: "" },
},
data() {
return {
editor: null,
};
},
created() {
// CDN引入(链接源自官方demo)
let src =
"https://microsoft.github.io/monaco-editor/node_modules/monaco-editor/min/vs/loader.js";
// public 引入
// let src = 'monaco-editor/min/vs/loader.js';
this.toCreateScript(src);
},
mounted() {
this.updateEditor(this.value);
},
watch: {
value: function (val) {
this.updateEditor(val);
},
},
methods: {
loader() {
// 需要使用的是requirejs去加载AMD格式的monaco,而非node的require模块
// loader.js负责装载window.require,也可以单独使用requirejs而非自带的loader.js去加载
// 不要修改monaco-editor/min/vs路径,除非改源码,该版本的MonacoEnvironment不起作用,worker.main.js里面自维护的变量取的不是外面的
let require = window.require;
// CDN引入(链接源自官方demo)
let vsPath =
"https://microsoft.github.io/monaco-editor/node_modules/monaco-editor/min/vs";
// public 引入
// let vsPath = "monaco-editor/min/vs"
require.config({ paths: { vs: vsPath } });
require(["vs/editor/editor.main"], () => this.toCreate());
},
toCreate() {
if (!this.editor) {
monaco.editor.defineTheme("myTheme", {
base: "vs",
inherit: true,
rules: [{ background: "EDF9FA" }],
colors: {
"editor.foreground": "#000000",
"editor.background": "#EDF9FA",
"editorCursor.foreground": "#8B0000",
"editor.lineHighlightBackground": "#0000FF20",
"editorLineNumber.foreground": "#008800",
"editor.selectionBackground": "#88000030",
"editor.inactiveSelectionBackground": "#88000015",
},
});
monaco.editor.setTheme("myTheme");
this.editor = monaco.editor.create(this.$refs.editor, {
value: "",
language: this.language,
lineNumbers: "off",
roundedSelection: false,
scrollBeyondLastLine: false,
readOnly: !this.editable,
theme: "vs-dark",
automaticLayout: true,
wordWrap: "wordWrapColumn",
wordWrapColumn: 40,
// Set this to false to not auto word wrap minified files
wordWrapMinified: true,
// try "same", "indent" or "none"
wrappingIndent: "indent",
scrollbar: {
// Subtle shadows to the left & top. Defaults to true.
useShadows: false,
// Render vertical arrows. Defaults to false.
verticalHasArrows: false,
// Render horizontal arrows. Defaults to false.
horizontalHasArrows: false,
// Render vertical scrollbar.
// Accepted values: 'auto', 'visible', 'hidden'.
// Defaults to 'auto'
vertical: "auto",
// Render horizontal scrollbar.
// Accepted values: 'auto', 'visible', 'hidden'.
// Defaults to 'auto'
horizontal: "auto",
verticalScrollbarSize: 10,
horizontalScrollbarSize: 10,
arrowSize: 10,
},
//小地图
minimap: {
enabled: false,
},
});
this.editor.onDidChangeModelContent(() => {
this.$emit("input", this.editor.getValue());
});
}
},
toCreateScript(src) {
let head = document.querySelector("head");
let script = document.createElement("script");
script.onload = () => this.loader();
script.onerror = () => {
head.removeChild(script);
};
script.src = src;
head.appendChild(script);
},
updateEditor(content) {
if (this.editor) {
if (content != this.editor.getValue()) this.editor.setValue(content);
this.editor.updateOptions({
readOnly: !this.editable,
});
}
},
},
};
</script>
2.1.1 —— 若public引入请先下载对应的资源:
- 官网下载链接
- npm 引入monaco包,对应的位置是node_modules/monaco-editor/min/vs
- 下载官网demo链接那些js(麻烦,不够全)
2.2 —— 组件调用:
<template>
<CodeEditor
v-model="content"
:language="language"
/>
</template>
<script>
import CodeEditor from '@/components/CodeEditor.vue'
export default {
components: { CodeEditor },
data() {
return {
content: '潇风剑易水',
language: '',
}
},
}
</script>
二:常见问题:
1 —— 待更:
三:吹水:
1 官网的文档并不是很好,例子多,但是有些是提及又缺少一些指引,然后就是api文档,这个很多没有具体的东西,有些深的自定义需要自己去看代码才知晓,不同版本的配置有点大,网上的案例涉及的配置也很多不适用,本文也仅仅针对这个版本的,但是相对来说还是可用
2 模块引入需要大幅度调整按需引入,否则即使webpack那个插件排除一些语言,还是编译过久,目前仅推荐静态引入,非模块引入,且这种不太涉及业务的不该由业务所在的模块管理里面,应该独立出去