Monaco-editor,一个vs code 编辑器,需要将其集成到项目。不说闲话了,直接上代码。
npm地址:https://www.npmjs.com/package/monaco-editor
中文文档:https://aydk.site/editor/
安装:
pnpm add monaco-editor -S
pnpm add vite-plugin-monaco-editor -D
配置:
vite.config.ts
import { defineConfig} from 'vite'// vs code 编辑器配置
import monacoEditorPlugin from 'vite-plugin-monaco-editor'// https://vitejs.dev/config/
export default ({ mode }) => {return defineConfig({plugins: [monacoEditorPlugin({languageWorkers: ['editorWorkerService', 'typescript', 'json', 'html']})]})
}
封装:
首先先封装个hook如下:
@/hooks/useMonacoEditor.hook.ts
import * as monaco from 'monaco-editor'
import useCommonStore from '@/store/common'
import { ref, nextTick, onBeforeUnmount } from 'vue'export function useMonacoEditor(language: string = 'javascript') {// 编辑器示例let monacoEditor: monaco.editor.IStandaloneCodeEditor | null = null// 目标元素const monacoEditorRef = ref<HTMLElement | null>(null)// 创建实例function createEditor(editorOption: monaco.editor.IStandaloneEditorConstructionOptions = {}) {if(!monacoEditorRef.value) returnmonacoEditor = monaco.editor.create(monacoEditorRef.value, {// 初始模型model: monaco.editor.createModel('', language),// 是否启用预览图minimap: { enabled: true },// 圆角roundedSelection: true,// 主题theme: useCommonStore().mode == 'dark' ? 'vs-dark' : 'vs',// 主键multiCursorModifier: 'ctrlCmd',// 滚动条scrollbar: {verticalScrollbarSize: 8,horizontalScrollbarSize: 8},// 行号lineNumbers: 'on',// tab大小tabSize: 2,//字体大小fontSize: 16,// 控制编辑器在用户键入、粘贴、移动或缩进行时是否应自动调整缩进autoIndent: 'advanced',// 自动布局automaticLayout: true,...editorOption})return monacoEditor}// 格式化async function formatDoc() {await monacoEditor?.getAction('editor.action.formatDocument')?.run()}// 数据更新function updateVal(val: string) {nextTick(() => {if(getOption(monaco.editor.EditorOption.readOnly)) {updateOptions({ readOnly: false })}monacoEditor?.setValue(val)setTimeout(async () => {await formatDoc()}, 10)})}// 配置更新function updateOptions(opt: monaco.editor.IStandaloneEditorConstructionOptions) {monacoEditor?.updateOptions(opt)}// 获取配置function getOption(name: monaco.editor.EditorOption) {return monacoEditor?.getOption(name)}// 获取实例function getEditor() {return monacoEditor}// 页面离开 销毁onBeforeUnmount(() => {if(monacoEditor) {monacoEditor.dispose()}})return {monacoEditorRef,createEditor,getEditor,updateVal,updateOptions,getOption,formatDoc}
}
然后调用上面 useMonacoEditor 封装editor编辑器组件
@/components/MonacoEditor/index.vue
<template><div ref="monacoEditorRef" :style="monacoEditorStyle"></div>
</template>
<script setup lang="ts">
import { useMonacoEditor } from '@/hooks'
import { onMounted, computed, watch } from 'vue'const props = withDefaults(defineProps<{width?: string | number,height?: string | number,language?: string,editorOption?: Object,modelValue: string
}>(), {width: '100%',height: '100%',language: 'javascript',editorOption: () => ({}),modelValue: ''
})const emits = defineEmits<{(e: 'blue'): void,(e: 'update:modelValue', val: string): void
}>()const monacoEditorStyle = computed(() => {return { width: typeof props.width === 'string' ? props.width : props.width + 'px', height: typeof props.height === 'string' ? props.height : props.height + 'px'}
})const { monacoEditorRef, createEditor, updateVal, updateOptions, getEditor } = useMonacoEditor(props.language)onMounted(() => {const monacoEditor = createEditor(props.editorOption)updateMonacoVal(props.modelValue)monacoEditor?.onDidChangeModelContent(() => {emits('update:modelValue', monacoEditor!.getValue())})monacoEditor?.onDidBlurEditorText(() => {emits('blue')})
})watch(() => props.modelValue, () => {updateMonacoVal(props.modelValue)
})function updateMonacoVal(val: string) {if(val !== getEditor()?.getValue()) {updateVal(val)}
}defineExpose({ updateOptions })
</script>
组件使用:
<div class="edit-container"><MonacoEditor ref="MonacoEditRef" v-model="editJson" language="json" />
</div>
<script setup lang="ts">
import MonacoEditor from '@/components/MonacoEditor/index.vue'
import { ref } from 'vue'let editJson = ref('')const MonacoEditRef = ref<InstanceType<typeof MonacoEditor>>()//MonacoEditRef.value!.updateOptions({ theme: 'vs' }) 调用子组件方法修改配置
</script>