当前位置:   article > 正文

Vue3使用Monaco-editor_vite-plugin-monaco-editor

vite-plugin-monaco-editor

Monaco-editor,一个vs code 编辑器,需要将其集成到项目。不说闲话了,直接上代码。 

npm地址:https://www.npmjs.com/package/monaco-editor

中文文档:https://aydk.site/editor/

安装:

  1. pnpm add monaco-editor -S
  2. pnpm add vite-plugin-monaco-editor -D

配置: 

vite.config.ts

  1. import { defineConfig} from 'vite'
  2. // vs code 编辑器配置
  3. import monacoEditorPlugin from 'vite-plugin-monaco-editor'
  4. // https://vitejs.dev/config/
  5. export default ({ mode }) => {
  6. return defineConfig({
  7. plugins: [
  8. monacoEditorPlugin({
  9. languageWorkers: ['editorWorkerService', 'typescript', 'json', 'html']
  10. })
  11. ]
  12. })
  13. }

封装: 

 首先先封装个hook如下:

@/hooks/useMonacoEditor.hook.ts 

  1. import * as monaco from 'monaco-editor'
  2. import useCommonStore from '@/store/common'
  3. import { ref, nextTick, onBeforeUnmount } from 'vue'
  4. export function useMonacoEditor(language: string = 'javascript') {
  5. // 编辑器示例
  6. let monacoEditor: monaco.editor.IStandaloneCodeEditor | null = null
  7. // 目标元素
  8. const monacoEditorRef = ref<HTMLElement | null>(null)
  9. // 创建实例
  10. function createEditor(editorOption: monaco.editor.IStandaloneEditorConstructionOptions = {}) {
  11. if(!monacoEditorRef.value) return
  12. monacoEditor = monaco.editor.create(monacoEditorRef.value, {
  13. // 初始模型
  14. model: monaco.editor.createModel('', language),
  15. // 是否启用预览图
  16. minimap: { enabled: true },
  17. // 圆角
  18. roundedSelection: true,
  19. // 主题
  20. theme: useCommonStore().mode == 'dark' ? 'vs-dark' : 'vs',
  21. // 主键
  22. multiCursorModifier: 'ctrlCmd',
  23. // 滚动条
  24. scrollbar: {
  25. verticalScrollbarSize: 8,
  26. horizontalScrollbarSize: 8
  27. },
  28. // 行号
  29. lineNumbers: 'on',
  30. // tab大小
  31. tabSize: 2,
  32. //字体大小
  33. fontSize: 16,
  34. // 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进
  35. autoIndent: 'advanced',
  36. // 自动布局
  37. automaticLayout: true,
  38. ...editorOption
  39. })
  40. return monacoEditor
  41. }
  42. // 格式化
  43. async function formatDoc() {
  44. await monacoEditor?.getAction('editor.action.formatDocument')?.run()
  45. }
  46. // 数据更新
  47. function updateVal(val: string) {
  48. nextTick(() => {
  49. if(getOption(monaco.editor.EditorOption.readOnly)) {
  50. updateOptions({ readOnly: false })
  51. }
  52. monacoEditor?.setValue(val)
  53. setTimeout(async () => {
  54. await formatDoc()
  55. }, 10)
  56. })
  57. }
  58. // 配置更新
  59. function updateOptions(opt: monaco.editor.IStandaloneEditorConstructionOptions) {
  60. monacoEditor?.updateOptions(opt)
  61. }
  62. // 获取配置
  63. function getOption(name: monaco.editor.EditorOption) {
  64. return monacoEditor?.getOption(name)
  65. }
  66. // 获取实例
  67. function getEditor() {
  68. return monacoEditor
  69. }
  70. // 页面离开 销毁
  71. onBeforeUnmount(() => {
  72. if(monacoEditor) {
  73. monacoEditor.dispose()
  74. }
  75. })
  76. return {
  77. monacoEditorRef,
  78. createEditor,
  79. getEditor,
  80. updateVal,
  81. updateOptions,
  82. getOption,
  83. formatDoc
  84. }
  85. }

然后调用上面 useMonacoEditor 封装editor编辑器组件

@/components/MonacoEditor/index.vue 

  1. <template>
  2. <div ref="monacoEditorRef" :style="monacoEditorStyle"></div>
  3. </template>
  4. <script setup lang="ts">
  5. import { useMonacoEditor } from '@/hooks'
  6. import { onMounted, computed, watch } from 'vue'
  7. const props = withDefaults(defineProps<{
  8. width?: string | number,
  9. height?: string | number,
  10. language?: string,
  11. editorOption?: Object,
  12. modelValue: string
  13. }>(), {
  14. width: '100%',
  15. height: '100%',
  16. language: 'javascript',
  17. editorOption: () => ({}),
  18. modelValue: ''
  19. })
  20. const emits = defineEmits<{
  21. (e: 'blue'): void,
  22. (e: 'update:modelValue', val: string): void
  23. }>()
  24. const monacoEditorStyle = computed(() => {
  25. return {
  26. width: typeof props.width === 'string' ? props.width : props.width + 'px',
  27. height: typeof props.height === 'string' ? props.height : props.height + 'px'
  28. }
  29. })
  30. const { monacoEditorRef, createEditor, updateVal, updateOptions, getEditor } = useMonacoEditor(props.language)
  31. onMounted(() => {
  32. const monacoEditor = createEditor(props.editorOption)
  33. updateMonacoVal(props.modelValue)
  34. monacoEditor?.onDidChangeModelContent(() => {
  35. emits('update:modelValue', monacoEditor!.getValue())
  36. })
  37. monacoEditor?.onDidBlurEditorText(() => {
  38. emits('blue')
  39. })
  40. })
  41. watch(() => props.modelValue, () => {
  42. updateMonacoVal(props.modelValue)
  43. })
  44. function updateMonacoVal(val: string) {
  45. if(val !== getEditor()?.getValue()) {
  46. updateVal(val)
  47. }
  48. }
  49. defineExpose({ updateOptions })
  50. </script>

组件使用: 

  1. <div class="edit-container">
  2. <MonacoEditor ref="MonacoEditRef" v-model="editJson" language="json" />
  3. </div>
  4. <script setup lang="ts">
  5. import MonacoEditor from '@/components/MonacoEditor/index.vue'
  6. import { ref } from 'vue'
  7. let editJson = ref('')
  8. const MonacoEditRef = ref<InstanceType<typeof MonacoEditor>>()
  9. //MonacoEditRef.value!.updateOptions({ theme: 'vs' }) 调用子组件方法修改配置
  10. </script>
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/710218
推荐阅读
相关标签
  

闽ICP备14008679号