Vue 中使用 Monaco Editor


最近的使命就是,在找好用的代碼編輯器🤪
嘗試了codeMirror 感覺咋用咋不順手,簡單的代碼編輯還能應付,復雜一點的配置就搞得頭昏眼花🙄,而且和 vue 一起用簡直命里犯沖🤬
機緣巧合就找到了救世主 Monaco Editor

安裝配置

npm官網

  1. npm i monaco-editor
  2. npm install monaco-editor-webpack-plugin --save-dev
  3. vue.config.js文件配置
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin')
module.exports = {
  chainWebpack: (config) => {
    config.plugin('monaco').use(new MonacoWebpackPlugin())
  }
}

代碼編輯

用到了"element-ui": "^2.15.6"

<template>
  <div class="myEditor">
          <el-form :inline="true" ref="form">
              <el-form-item>
                  <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>
              </el-form-item>
              <el-form-item>
                  <el-select v-model="language" size="mini" filterable @change="languageChange" placeholder="語言">
                      <el-option
                              v-for="item in languageOption"
                              :key="item.id"
                              :label="item.id"
                              :value="item.id">
                      </el-option>
                  </el-select>
              </el-form-item>
          </el-form>
      <div id="container" ref="container"></div>
  </div>
</template>
<script>
import * as monaco from 'monaco-editor'
export default {
  data () {
    return {
      themeOption: [
        {
          value: 'vs',
          label: '默認'
        },
        {
          value: 'hc-black',
          label: '高亮'
        },
        {
          value: 'vs-dark',
          label: '深色'
        }
      ],
      languageOption: [],
      theme: 'vs',
      language: 'plaintext'
    }
  },
  mounted () {
    const self = this
    self.initEditor()
    self.languageOption = monaco.languages.getLanguages()
  },
  methods: {
    initEditor () {
      const self = this
      const domEditor = document.getElementById('container')
      self.monacoEditor = monaco.editor.create(domEditor, {
        theme: self.theme,
        readOnly: false,
        automaticLayout: true
      })
    },
    themeChange (val) {
      monaco.editor.setTheme(val)
    },
    languageChange (val) {
      monaco.editor.setModelLanguage(this.monacoEditor.getModel(), val)
    }
  }
}
</script>
<style scoped>
  #container{
      width: 100vw;
      height: calc(100vh - 41px);
    text-align: left;
  }
  .el-form-item{
      margin-bottom: 0;
      margin-left: 10px;
  }
</style>

代碼對比

用到了"element-ui": "^2.15.6"

<template>
  <div class="myEditor">
          <el-form :inline="true" ref="form">
              <el-form-item>
                  <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>
              </el-form-item>
              <el-form-item>
                  <el-select v-model="language" size="mini" filterable @change="languageChange" placeholder="比對語言">
                      <el-option
                              v-for="item in languageOption"
                              :key="item.id"
                              :label="item.id"
                              :value="item.id">
                      </el-option>
                  </el-select>
              </el-form-item>
              <el-form-item style="float: right">
                  {{diffNum}}處差異
              </el-form-item>
          </el-form>
      <div id="container" ref="container"></div>
  </div>
</template>
<script>
import * as monaco from 'monaco-editor'
export default {
  data () {
    return {
      themeOption: [
        {
          value: 'vs',
          label: '默認'
        },
        {
          value: 'hc-black',
          label: '高亮'
        },
        {
          value: 'vs-dark',
          label: '深色'
        }
      ],
      languageOption: [],
      theme: 'vs',
      language: 'plaintext',
      diffNum: 0
    }
  },
  mounted () {
    const self = this
    self.initEditor()
    self.setModel('', '')
    self.languageOption = monaco.languages.getLanguages()
  },
  methods: {
    initEditor () {
      const self = this
      const domEditor = document.getElementById('container')
      self.monacoEditor = monaco.editor.createDiffEditor(domEditor, {
        theme: self.theme,
        readOnly: false,
        domReadOnly: false,
        originalEditable: true,
        automaticLayout: true
      })
      self.monacoEditor.onDidUpdateDiff(()=>{
        self.diffNum = this.monacoEditor.getLineChanges().length
      })
    },
    themeChange (val) {
      monaco.editor.setTheme(val)
    },
    languageChange (val) {
      console.log(val);
      monaco.editor.setModelLanguage(this.monacoEditor.getModel().original, val)
      monaco.editor.setModelLanguage(this.monacoEditor.getModel().modified, val)
    },
    setModel (original, modified) {
      this.monacoEditor.setModel({
        original: monaco.editor.createModel(original, this.language),
        modified: monaco.editor.createModel(modified, this.language)
      })
    }
  }
}
</script>
<style scoped>
  #container{
      width: 100vw;
      height: calc(100vh - 41px);
    text-align: left;
  }
  .el-form-item{
      margin-bottom: 0;
      margin-left: 10px;
  }
</style>

代碼對比增加下一處差異功能

monaco提供的方法會直接跳轉到指定的差異位置。

// 創建差異指南
self.diffNavigator = monaco.editor.createDiffNavigator(this.monacoEditor,{
        alwaysRevealFirst:true
      })
// 上一處差異
self.diffNavigator.previous()
// 下一處差異
self.diffNavigator.next()

右鍵面板增加操作

self.monacoEditor.addAction({
        id: 'nextDiff', // 菜單項 id
        label: '上一處差異', // 菜單項名稱
        keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.PageUp], // 綁定快捷鍵,是 monacoEditor 自定義的對應關系
        contextMenuGroupId: 'navigation', // 所屬菜單的分組
        run: () => self.nextDiff(), // 點擊后執行的操作
      })
self.monacoEditor.addAction({
        id: 'nextDiff', // 菜單項 id
        label: '下一處差異', // 菜單項名稱
        keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.PageDown], // 綁定快捷鍵
        contextMenuGroupId: 'navigation', // 所屬菜單的分組
        run: () => self.nextDiff(), // 點擊后執行的操作
      })

部分配置解釋

配置名稱 功能
automaticLayout 自適應布局
readOnly 只讀
theme 主題
originalEditable 源比較代碼可編輯(代碼對比)

才藝展示

代碼編輯

代碼對比

參考

官網
時間脫臼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM