Vue cli2.0 项目中使用Monaco Editor编辑器

monaco-editor 是微软出的一条开源web在线编辑器
支持多种语言,代码高亮,代码提示等功能,与Visual Studio Code 功能几乎相同。

在项目中可能会用带代码编辑功能,或者展示代码。对于习惯使用vsCode的开发者来说使用monaco-editor是非常不错的选择。

安装依赖

cnpm install monaco-editor --save

cnpm install monaco-editor-webpack-plugin --save-dev //webpack 4.x 以上版本不需要执行此命令

修改webpack.base.conf.js配置文件,如图:

const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
...

module.exports = {
  ...
  plugins: [
    ...
    new MonacoWebpackPlugin()
  ]
};

 

editor组件

<template>
    <div class="myEditor">
        <p>
            <el-button type="success" icon="el-icon-check" circle @click="RunResult"></el-button>
            <span class="theme" style="float:right">
                <el-select v-model="theme" size="mini" @change="themeChange" placeholder="请选择主题">
                    <el-option
                        v-for="item in themeOption"
                        :key="item.value"
                        :label="item.label"
                        :value="item.value">
                    </el-option>
                </el-select>
            </span>
        </p>
        <div id="container" ref="container" style="height:600px"></div>
    </div>
</template>
<script>
import * as monaco from 'monaco-editor';
export default {
    props:{
        codes:{
            type:String,
            default:function(){
                return '<div>请编辑html内容</div>'
            }
        },
        language:{
            type:String,
            default:function(){
                return 'html'
            }
        },
        editorOptions:{
            type:Object,
            default:function(){
                return {
                    selectOnLineNumbers: true,
                    roundedSelection: false,
                    readOnly: false,		// 只读
                    cursorStyle: 'line',		//光标样式
                    automaticLayout: false,	//自动布局
                    glyphMargin: true,  //字形边缘
                    useTabStops: false,
                    fontSize: 28,		//字体大小
                    autoIndent:true,//自动布局
                    //quickSuggestionsDelay: 500,	//代码提示延时
                }
            }
        }
    },
    data(){
        return{
            themeOption:[
                {
                    value:'vs',
                    label:'默认'
                },
                {
                    value:'hc-black',
                    label:'高亮'
                },
                {
                    value:'vs-dark',
                    label:'深色'
                },
            ],
            theme:'hc-black',
            codesCopy:null,//内容备份
        }
    },
    mounted(){
        this.initEditor();
    },
    methods:{
        initEditor(){
            let self = this;
            self.$refs.container.innerHTML = '';
            self.monacoEditor = monaco.editor.create(self.$refs.container, {
                value:self.codesCopy || self.codes,
                language: self.language,
                theme: self.theme,//vs, hc-black, or vs-dark
                editorOptions:self.editorOptions,
            });
            self.$emit('onMounted',self.monacoEditor);//编辑器创建完成回调
            self.monacoEditor.onDidChangeModelContent(function(event){//编辑器内容changge事件
                self.codesCopy = self.monacoEditor.getValue();
                self.$emit('onCodeChange',self.monacoEditor.getValue(),event);
            });
            //编辑器随窗口自适应
            window.addEventListener('resize',function(){
                initEditor();
            })
        },
        RunResult(){
            console.log(this.monacoEditor.getValue());
        },
        themeChange(val){
            this.initEditor();
        }
    }
}
</script>
<style scoped>
    #container{
        height:100%;
        text-align: left;
    }
</style>

  

引用editor组件

<template>
  <div>
    <el-tabs type="border-card">
      <el-tab-pane :lazy="true">
        <span slot="label"><i class="el-icon-document"></i> HTML</span>
        <MyEditor
          :language="'html'"
          :codes="htmlCodes"
          @onMounted="htmlOnMounted"
          @onCodeChange="htmlOnCodeChange" />
      </el-tab-pane>
      <el-tab-pane label="Javascript" :lazy="true">
        <MyEditor
          :language="'javascript'"
          :codes="javascriptCodes"
          @onMounted="javascriptOnMounted"
          @onCodeChange="javascriptOnCodeChange" />
      </el-tab-pane>
      <el-tab-pane label="CSS" :lazy="true">
        <MyEditor
          :language="'css'"
          :codes="cssCodes"
          @onMounted="cssOnMounted"
          @onCodeChange="cssOnCodeChange" />
      </el-tab-pane>
    </el-tabs>
  </div>
</template>

<script>
 import MyEditor from './myEditor'
export default {
  components:{
    MyEditor
  },
  data () {
    return {
      htmlCodes:'<div>This is html</div>',
      javascriptCodes:'console.log("This is javascript")',
      cssCodes:'body{}',
      htmlEditor:null,
      jsEditor:null,
      cssEditor:null,
    }
  },
  methods:{
    htmlOnMounted(edit){
      this.htmlEditor = edit;
    },
    javascriptOnMounted(edit){
      this.jsEditor = edit;
    },
    cssOnMounted(edit){
      this.cssEditor = edit;
    },
    htmlOnCodeChange(value,event){},
    javascriptOnCodeChange(value,event){},
    cssOnCodeChange(value,event){},
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>

</style>

效果图如下:

 

posted @ 2018-09-17 17:19  时间脱臼  阅读(13113)  评论(4编辑  收藏  举报