Skip to content

Commit 3e79920

Browse files
committed
Monaco Editor for Vue
0 parents  commit 3e79920

File tree

3 files changed

+254
-0
lines changed

3 files changed

+254
-0
lines changed

README.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# vue-monaco-editor
2+
3+
> [Monaco Editor](https://github.com/Microsoft/monaco-editor) for Vue.
4+
5+
[![NPM version][npm-image]][npm-url]
6+
[![Downloads][downloads-image]][npm-url]
7+
8+
[![monaco-editor-vue](https://nodei.co/npm/monaco-editor-vue.png)](https://npmjs.org/package/monaco-editor-vue)
9+
10+
[npm-url]: https://www.npmjs.com/package/monaco-editor-vue
11+
[downloads-image]: http://img.shields.io/npm/dm/monaco-editor-vue.svg
12+
[npm-image]: http://img.shields.io/npm/v/monaco-editor-vue.svg
13+
14+
## Installation
15+
16+
```bash
17+
npm install monaco-editor-vue
18+
```
19+
20+
## Using with Webpack
21+
22+
```js
23+
<template>
24+
<div id="app">
25+
<MonacoEditor
26+
width="800"
27+
height="500"
28+
theme="vs-dark"
29+
language="javascript"
30+
options={options}
31+
@change="onChange"
32+
></MonacoEditor>
33+
</div>
34+
</template>
35+
36+
<script>
37+
import MonacoEditor from 'monaco-editor-vue';
38+
export default {
39+
name: "App",
40+
components: {
41+
MonacoEditor
42+
},
43+
data() {
44+
return {
45+
options: {
46+
//Monaco Editor Options
47+
}
48+
}
49+
},
50+
methods: {
51+
onChange(value) {
52+
console.log(value);
53+
}
54+
}
55+
};
56+
</script>
57+
```
58+
59+
Add the [Monaco Webpack plugin](https://github.com/Microsoft/monaco-editor-webpack-plugin) `monaco-editor-webpack-plugin` to your `webpack.config.js`:
60+
61+
```js
62+
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
63+
module.exports = {
64+
plugins: [
65+
new MonacoWebpackPlugin({
66+
// available options are documented at https://github.com/Microsoft/monaco-editor-webpack-plugin#options
67+
languages: ['javascript']
68+
})
69+
]
70+
};
71+
```
72+
73+
## Properties
74+
75+
If you specify `value` property, the component behaves in controlled mode.
76+
Otherwise, it behaves in uncontrolled mode.
77+
78+
- `width` width of editor. Defaults to `100%`.
79+
- `height` height of editor. Defaults to `100%`.
80+
- `value` value of the auto created model in the editor.
81+
- `language` the initial language of the auto created model in the editor. Defaults to `javascript`.
82+
- `theme` the theme of the editor. Defaults to `vs`.
83+
- `options` refer to [Monaco interface IEditorConstructionOptions](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.ieditorconstructionoptions.html).
84+
- `change(newValue, event)` an event emitted when the content of the current model has changed.
85+
- `editorBeforeMount(monaco)` an event emitted before the editor mounted (similar to `beforeMount` of Vue).
86+
- `editorMounted(editor, monaco)` an event emitted when the editor has been mounted (similar to `mounted` of Vue).
87+
88+
## Events & Methods
89+
90+
Refer to [Monaco interface IEditor](https://microsoft.github.io/monaco-editor/api/interfaces/monaco.editor.ieditor.html).
91+
92+
### Use multiple themes
93+
94+
[Monaco only supports one theme](https://github.com/Microsoft/monaco-editor/issues/338).
95+
96+
### How to use the diff editor
97+
98+
```js
99+
<template>
100+
<div id="app">
101+
<MonacoEditor
102+
:diffEditor="true"
103+
original="..."
104+
//...
105+
></MonacoEditor>
106+
</div>
107+
</template>
108+
```

package.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"name": "monaco-editor-vue",
3+
"version": "1.0.1",
4+
"description": "Monaco Editor for Vue.",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"dependencies": {
10+
"monaco-editor": "^0.15.6",
11+
},
12+
"keywords": [
13+
"Vue",
14+
"monaco",
15+
"monaco-editor",
16+
"vue-monaco-editor",
17+
"monaco-editor-vue"
18+
],
19+
"author": "jwong",
20+
"license": "MIT"
21+
}

src/index.js

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
2+
3+
function noop() { }
4+
5+
export default {
6+
name: 'MonacoEditor',
7+
props: {
8+
diffEditor: { type: Boolean, default: false }, //是否使用diff模式
9+
width: {type: [String, Number], default: '100%'},
10+
height: {type: [String, Number], default: '100%'},
11+
original: String, //只有在diff模式下有效
12+
value: String,
13+
language: {type: String, default: 'javascript'},
14+
theme: {type: String, default: 'vs'},
15+
options: {type: Object, default() {return {};}},
16+
editorMounted: {type: Function, default: noop},
17+
editorBeforeMount: {type: Function, default: noop}
18+
},
19+
20+
watch: {
21+
options: {
22+
deep: true,
23+
handler(options) {
24+
this.editor && this.editor.updateOptions(options)
25+
}
26+
},
27+
28+
value() {
29+
this.editor && this.value !== this.editor.getValue() && this.editor.setValue(this.value);
30+
},
31+
32+
language() {
33+
if(!this.editor) return;
34+
if(this.diffEditor){ //diff模式下更新language
35+
const { original, modified } = this.editor.getModel();
36+
monaco.editor.setModelLanguage(original, this.language);
37+
monaco.editor.setModelLanguage(modified, this.language);
38+
}else
39+
monaco.editor.setModelLanguage(this.editor.getModel(), this.language);
40+
},
41+
42+
theme() {
43+
this.editor && monaco.editor.setTheme(this.theme);
44+
},
45+
46+
style() {
47+
this.editor && this.$nextTick(() => {
48+
this.editor.layout();
49+
});
50+
}
51+
},
52+
53+
computed: {
54+
style() {
55+
return {
56+
width: !/^\d+$/.test(this.width) ? this.width : `${this.width}px`,
57+
height: !/^\d+$/.test(this.height) ? this.height : `${this.height}px`
58+
}
59+
}
60+
},
61+
62+
mounted () {
63+
this.initMonaco();
64+
},
65+
66+
beforeDestroy() {
67+
this.editor && this.editor.dispose();
68+
},
69+
70+
render (h) {
71+
return (
72+
<div class="monaco_editor_container" style={this.style}></div>
73+
);
74+
},
75+
76+
methods: {
77+
initMonaco() {
78+
const { value, language, theme, options } = this;
79+
Object.assign(options, this._editorBeforeMount()); //编辑器初始化前
80+
this.editor = monaco.editor[this.diffEditor ? 'createDiffEditor' : 'create'](this.$el, {
81+
value: this.value,
82+
language: this.language,
83+
theme: this.theme,
84+
...options
85+
});
86+
this.diffEditor && this._setModel(this.value, this.original);
87+
this._editorMounted(this.editor); //编辑器初始化后
88+
},
89+
90+
_setModel(value, original) { //diff模式下设置model
91+
const { language } = this;
92+
const originalModel = monaco.editor.createModel(original, language);
93+
const modifiedModel = monaco.editor.createModel(value, language);
94+
this.editor.setModel({
95+
original: originalModel,
96+
modified: modifiedModel
97+
});
98+
},
99+
100+
_editorBeforeMount() {
101+
const options = this.editorBeforeMount(monaco);
102+
return options || {};
103+
},
104+
105+
_editorMounted(editor) {
106+
this.editorMounted(editor, monaco);
107+
if(this.diffEditor){
108+
editor.onDidUpdateDiff(() => {
109+
const value = editor.getModel().modified.getValue();
110+
this._emitChange(value, event);
111+
});
112+
}else{
113+
editor.onDidChangeModelContent(event => {
114+
const value = editor.getValue();
115+
this._emitChange(value, event);
116+
});
117+
}
118+
},
119+
120+
_emitChange(value, event) {
121+
this.$emit('change', value, event);
122+
this.$emit('input', value);
123+
}
124+
}
125+
}

0 commit comments

Comments
 (0)