集成 Vue 3 Vitest 和 Monaco 编辑器

问题描述 投票:0回答:1

有人知道如何将 vue 3 与 vitest 和 monaco 编辑器集成吗?我的代码现在看起来像这样:它实际上可以工作,但是许多样式看起来确实有错误,我开始相信,我做错了什么。当我想使用该房产时 行号:“打开”,这不起作用,我无法看到每行的数字,我在左上角也看到了一个奇怪的图标,而且宽度看起来也不正确。

它应该是什么样子:

代码编辑器.vue

<template>
  <div class="code-editor">
    <div ref="codeEditorBox" class="code-editor-box"></div>
  </div>
</template>

<script lang="ts">
import { defineComponent, onMounted, ref, watch } from 'vue'
import { editorProps } from './monacoEditorType'
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'

export default defineComponent({
  props: editorProps,
  emits: ['update:value', 'change', 'editor-mounted'],
  setup(props, { emit }) {
    self.MonacoEnvironment = {
      getWorker(_, label) {
        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()
      },
    }

    let editor: monaco.editor.IStandaloneCodeEditor
    const codeEditorBox = ref()

    const init = () => {
      monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions({
        noSemanticValidation: true,
        noSyntaxValidation: false,
      })
      monaco.languages.typescript.javascriptDefaults.setCompilerOptions({
        target: monaco.languages.typescript.ScriptTarget.ES2020,
        allowNonTsExtensions: true,
      })

      editor = monaco.editor.create(codeEditorBox.value, {
        value: props.value,
        language: props.language,
        theme: props.theme,
        ...props.options,
      })

      editor.onDidChangeModelContent(() => {
        const value = editor.getValue()
        emit('update:value', value)
        emit('change', value)
      })

      emit('editor-mounted', editor)
    }
    watch(
      () => props.value,
      (newValue) => {
        if (editor) {
          const value = editor.getValue()
          if (newValue !== value) {
            editor.setValue(newValue)
          }
        }
      },
    )
    watch(
      () => props.options,
      (newValue) => {
        editor.updateOptions(newValue)
      },
      { deep: true },
    )

    watch(
      () => props.language,
      (newValue) => {
        monaco.editor.setModelLanguage(editor.getModel()!, newValue)
      },
    )

    onMounted(() => {
      init()
    })

    return { codeEditorBox, props }
  },
})
</script>
<style lang="postcss">

.code-editor-box {
  width: v-bind(width);
  height: v-bind(height);
}
.code-editor-box-language {
  @apply bg-color-surface-variant py-2 pl-4;
  width: calc(v-bind(width) - pl-4);
}

.code-editor {
  width: v-bind(width);
  @apply border-[1px] border-solid border-color-outline rounded;
}
</style>

MonacoEditorTypes.ts

import type { PropType } from 'vue'
export type Theme = 'vs' | 'hc-black' | 'vs-dark'
export type FoldingStrategy = 'auto' | 'indentation'
export type RenderLineHighlight = 'all' | 'line' | 'none' | 'gutter'
export type lineDecorationsWidth = 'number' | 'string'
export type lineNumbers = 'on' | 'off' | 'relative' | 'interval'
export type wordWrap = 'on' | 'off' | 'wordWrapColumn' | 'bounded'

// import type { editor } from 'monaco-editor/esm/vs/editor/editor.api'

export interface Options {
  glyphMargin: boolean
  codeLens: boolean
  automaticLayout: boolean
  foldingStrategy: FoldingStrategy
  renderLineHighlight: RenderLineHighlight
  selectOnLineNumbers: boolean
  minimap: {
    enabled: boolean
  }
  lineNumbers: lineNumbers
  lineNumbersMinChars: number
  lineDecorationsWidth: lineDecorationsWidth
  readOnly: boolean
  fontSize: number
  scrollBeyondLastLine: boolean
  overviewRulerBorder: boolean
  overviewRulerLanes: number
  wordWrap: wordWrap
}

export const editorProps = {
  value: {
    type: String as PropType<string>,
    default: null,
  },
  width: {
    type: [String, Number] as PropType<string | number>,
    default: '200px',
  },
  height: {
    type: [String, Number] as PropType<string | number>,
    default: '100%',
  },
  language: {
    type: String as PropType<string>,
    default: 'javascript',
  },
  theme: {
    type: String as PropType<Theme>,
    validator(value: string): boolean {
      return ['vs', 'hc-black', 'vs-dark'].includes(value)
    },
    default: 'vs',
  },
  options: {
    type: Object as PropType<Options>,
    default: function () {
      return {
        glyphMargin: true,
        codeLens: false,
        automaticLayout: true,
        foldingStrategy: 'indentation',
        renderLineHighlight: 'none',
        minimap: {
          enabled: false,
        },
        readOnly: true,
        fontSize: 16,
        scrollBeyondLastLine: false,
        overviewRulerBorder: false,
        overviewRulerLanes: 0,
        lineNumbers: 'on',
      }
    },
  },
}

示例.vue

已经导入了

      <code-editor
        :value="value"
        :language="language"
        width="500px"
        height="150px"
        @editor-mounted="editorMounted">
      </code-editor>

在我的设置函数中,我有这个 editorMounted const,我也返回它:

const editorMounted = (editor: monaco.editor.IStandaloneCodeEditor) => {
  console.log('editor', editor)
}

vite.config.ts添加

 optimizeDeps: {
    include: [
      `monaco-editor/esm/vs/language/json/json.worker`,
      `monaco-editor/esm/vs/language/css/css.worker`,
      `monaco-editor/esm/vs/language/html/html.worker`,
      `monaco-editor/esm/vs/language/typescript/ts.worker`,
      `monaco-editor/esm/vs/editor/editor.worker`,
    ],
  },
vuejs3 monaco-editor vitest
1个回答
0
投票

要格式化此代码,我使用:

 /// on first initialization format code
      editor.onDidChangeModelLanguageConfiguration(() => {
        editor?.getAction('editor.action.formatDocument')?.run()
      })

但是我还是没有得到左边的行号

© www.soinside.com 2019 - 2024. All rights reserved.