vue中使用monaco-editor实现代码编辑器

我们这里是以vue3为例,实现效果如下所示:

1、安装

npm install monaco-editor --save

yarn add monaco-editor --save

2、如何使用

我这里是将其封装成了一个组件来使用的,代码如下

<div ref="codeEditBox" class="code-edit-box" style="min-width: 500px; width: 100%; height:500px;"></div>

// 引入
import * as monaco from 'monaco-editor'
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'

// 代码编辑器 form 的 dom
const scriptFormRef = ref()

onMounted(() => {
  nextTick(() => {
     initEditor()
   })
})


/**
 * 初始化
 */
const initEditor = () => {
  self.MonacoEnvironment = {
    getWorker(_: any, label: string) {
      if (label === 'json') {
        return new jsonWorker()
      }
      if (label === 'css' || label === 'scss' || label === 'less') {
        return new cssWorker()
      }
      if (label === 'html' || label === 'handlebars' || label === 'razor') {
        return new htmlWorker()
      }
      if (label === 'typescript' || label === 'javascript') {
        return new tsWorker()
      }
      return new editorWorker()
    },
  }
  const editor = monaco.editor.create(codeEditBox.value, {
    value: '', // 默认显示内容
    theme: 'vs-dark', // 官方自带三种主题vs, hc-black, or vs-dark
    language: 'javascript',
  })
  editor.onDidChangeModelContent((val: any) => {
     console.log(editor.getValue()) // 实时获取输入的内容
  })
}

下面是我封装的完整代码,是结合el-dialog组件来实现的

<template>
  <el-dialog
    :model-value="scriptVisible"
    title="脚本配置"
    draggable
    class="public-dialog form-dialog"
    :close-on-click-modal="true"
    width="70%"
    append-to-body
    destroy-on-close
    @close="handleClose"
  >
    <el-form
      ref="scriptFormRef"
      :model="scriptForm"
      inline
      class="list-search-el-form"
      label-width="auto"
      :rules="rules"
    >
      <el-row>
        <el-col>
          <el-form-item label="脚本配置" prop="scriptType">
            <el-select v-model="scriptForm.scriptType">
              <el-option label="javaScript" value='javaScript' />
            </el-select>
          </el-form-item>
        </el-col>
        <el-col>
          <el-form-item label="脚本内容" prop="script" class='w100'>
            <div ref="codeEditBox" class="code-edit-box" style="min-width: 500px; width: 100%; height:500px;"></div>
          </el-form-item>
        </el-col>
      </el-row>
    </el-form>
    <template #footer>
      <el-button
        type='primary'
        @click='handleSave(scriptFormRef)'
      >保存</el-button>
      <el-button
        @click='handleClose'
      >取消</el-button>
    </template>
  </el-dialog>
</template>

<script lang='ts' setup>
import * as monaco from 'monaco-editor'
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
import type { FormInstance, FormRules } from 'element-plus'
const emit = defineEmits(['closeScriptModel','handleSaveScript'])
const props = defineProps({
  scriptVisible: { // 弹窗 开启 | 关闭
    type: Boolean,
    default: () => {
      return false
    },
  },
  editScriptType: { // 编辑类型
    type: String,
    default: () => {
      return ''
    },
  },
  checkedScriptItem: { // 当前编辑项
    type: Object,
    default: () => {
      return {}
    },
  },
  checkedScriptType: { // 编辑类型
    type: String,
    default: () => {
      return ''
    },
  },
})
// 代码编辑器 form 的 dom
const scriptFormRef = ref()
// 代码编辑器form
const scriptForm = ref({})
// 脚本id
const scriptId = ref(null)
// 代码编辑器dom
const codeEditBox = ref()
// 校验规则
const rules = ref<FormRules<FormRules>>({
  scriptType: [
    {
      required: true,
      message: '请选择脚本配置类型',
      trigger: 'change',
    },
  ],
  script: [
    {
      required: true,
      message: '请填写脚本配置内容',
      trigger: 'change',
    },
  ],
})
onMounted(() => {
  nextTick(() => {
    initEditor()
   })
})

/**
 * 初始化
 */
const initEditor = () => {
  self.MonacoEnvironment = {
    getWorker(_: any, label: string) {
      if (label === 'json') {
        return new jsonWorker()
      }
      if (label === 'css' || label === 'scss' || label === 'less') {
        return new cssWorker()
      }
      if (label === 'html' || label === 'handlebars' || label === 'razor') {
        return new htmlWorker()
      }
      if (label === 'typescript' || label === 'javascript') {
        return new tsWorker()
      }
      return new editorWorker()
    },
  }
  const editor = monaco.editor.create(codeEditBox.value, {
    value: scriptForm.value.script,
    theme: 'vs-dark', // 官方自带三种主题vs, hc-black, or vs-dark
    language: 'javascript',
  })
  editor.onDidChangeModelContent((val: any) => {
    scriptForm.value.script = editor.getValue()
  })
}


/**
 * 确定保存脚本
 */
const handleSave = async (formEl: FormInstance | undefined) => {
  if (!formEl) { return }
  await formEl.validate((valid, fields) => {
    if (valid) {
      console.log('submit')
   
    } else {
      console.log('error submit!', fields)
    }
  })
}
/**
 * 关闭脚本编辑
 */
const handleClose = () => {
  
}
</script>

<style scoped>

</style>

这样就可以实现一个简单的代码编辑器功能了,有问题可以随时私信!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值