添加 editor.
This commit is contained in:
92
orion-ops-ui/src/components/view/editor/core.ts
Normal file
92
orion-ops-ui/src/components/view/editor/core.ts
Normal file
@@ -0,0 +1,92 @@
|
||||
import JsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
|
||||
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
|
||||
|
||||
/**
|
||||
* 主题
|
||||
*/
|
||||
export type Theme = 'vs' | 'vs-dark'
|
||||
|
||||
/**
|
||||
* 折叠方式
|
||||
*/
|
||||
export type FoldingStrategy = 'auto' | 'indentation'
|
||||
|
||||
/**
|
||||
* 是否一直显示折叠
|
||||
*/
|
||||
export type ShowFoldingControls = 'always' | 'mouseover';
|
||||
|
||||
/**
|
||||
* 行亮
|
||||
*/
|
||||
export type RenderLineHighlight = 'all' | 'line' | 'none' | 'gutter'
|
||||
|
||||
/**
|
||||
* 配置项
|
||||
*/
|
||||
export interface Options {
|
||||
// 自适应布局
|
||||
automaticLayout?: boolean;
|
||||
// 是否折叠
|
||||
folding?: boolean;
|
||||
// 折叠方式
|
||||
foldingStrategy?: FoldingStrategy;
|
||||
// 是否折叠等高线
|
||||
foldingHighlight?: boolean;
|
||||
// 是否一直显示折叠
|
||||
showFoldingControls?: ShowFoldingControls;
|
||||
// 等宽优化
|
||||
disableLayerHinting?: boolean;
|
||||
// 行亮
|
||||
renderLineHighlight?: RenderLineHighlight;
|
||||
// 显示行号
|
||||
selectOnLineNumbers?: boolean;
|
||||
placeholder?: string;
|
||||
minimap?: {
|
||||
// 关闭小地图
|
||||
enabled?: boolean
|
||||
};
|
||||
fontSize?: number;
|
||||
// 取消代码后面一大段空白
|
||||
scrollBeyondLastLine?: boolean;
|
||||
// 不要滚动条的边框
|
||||
overviewRulerBorder?: boolean;
|
||||
// 颜色装饰器
|
||||
colorDecorators?: boolean;
|
||||
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建默认配置
|
||||
*/
|
||||
export const createDefaultOptions = (): Options => {
|
||||
return {
|
||||
automaticLayout: true,
|
||||
folding: true,
|
||||
foldingHighlight: true,
|
||||
foldingStrategy: 'indentation',
|
||||
showFoldingControls: 'always',
|
||||
renderLineHighlight: 'line',
|
||||
selectOnLineNumbers: true,
|
||||
disableLayerHinting: true,
|
||||
minimap: {
|
||||
enabled: false,
|
||||
},
|
||||
fontSize: 16,
|
||||
scrollBeyondLastLine: false,
|
||||
overviewRulerBorder: false,
|
||||
colorDecorators: true,
|
||||
suggest: true,
|
||||
};
|
||||
};
|
||||
|
||||
// worker 生成器
|
||||
self.MonacoEnvironment = {
|
||||
getWorker(_: string, label: string) {
|
||||
if (label === 'json') {
|
||||
return new JsonWorker();
|
||||
}
|
||||
return new EditorWorker();
|
||||
},
|
||||
};
|
||||
141
orion-ops-ui/src/components/view/editor/index.vue
Normal file
141
orion-ops-ui/src/components/view/editor/index.vue
Normal file
@@ -0,0 +1,141 @@
|
||||
<template>
|
||||
<div ref="editorContainer"
|
||||
:class="{
|
||||
'editor-wrapper': true,
|
||||
[containerClass]: !!containerClass
|
||||
}"
|
||||
:style="{
|
||||
...containerStyle
|
||||
}" />
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'index'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Theme, Options } from './core';
|
||||
import type { PropType } from 'vue';
|
||||
import * as monaco from 'monaco-editor';
|
||||
import { createDefaultOptions } from './core';
|
||||
import { onBeforeUnmount, onMounted, ref, watch } from 'vue';
|
||||
import { useAppStore } from '@/store';
|
||||
|
||||
const appStore = useAppStore();
|
||||
|
||||
const emits = defineEmits(['update:modelValue', 'change', 'editor-mounted']);
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: String,
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '100%'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '100%'
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
language: {
|
||||
type: String,
|
||||
default: 'json',
|
||||
},
|
||||
containerClass: String,
|
||||
containerStyle: Object,
|
||||
theme: {
|
||||
type: [String, Boolean] as PropType<Theme | boolean>,
|
||||
default: true,
|
||||
},
|
||||
options: {
|
||||
type: Object as PropType<Options>,
|
||||
default: () => {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const editorContainer = ref();
|
||||
let editor: any;
|
||||
|
||||
// 初始化
|
||||
const init = () => {
|
||||
const options = {
|
||||
value: props.modelValue,
|
||||
language: props.language,
|
||||
readOnly: props.readonly,
|
||||
theme: props.theme === true ? (appStore.theme === 'dark' ? 'vs-dark' : 'vs') : props.theme,
|
||||
options: { ...createDefaultOptions(), ...props.options },
|
||||
};
|
||||
// 创建编辑器
|
||||
editor = monaco.editor.create(editorContainer.value, options);
|
||||
// 监听值的变化
|
||||
editor.onDidChangeModelContent(() => {
|
||||
const value = editor.getValue();
|
||||
emits('update:modelValue', value);
|
||||
emits('change', value);
|
||||
});
|
||||
emits('editor-mounted', editor);
|
||||
};
|
||||
|
||||
// 监听主题变更
|
||||
watch(() => appStore.theme, (v) => {
|
||||
if (editor && props.theme === true) {
|
||||
editor.updateOptions({ theme: v === 'dark' ? 'vs-dark' : 'vs' });
|
||||
}
|
||||
});
|
||||
|
||||
// 监听数据变更
|
||||
watch(() => props.modelValue, (v) => {
|
||||
if (editor) {
|
||||
const value = editor.getValue();
|
||||
if (v !== value) {
|
||||
editor.setValue(v);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 监听配置
|
||||
watch(() => props.options, (v) => {
|
||||
if (editor) {
|
||||
editor.updateOptions(v);
|
||||
}
|
||||
}, { deep: true });
|
||||
|
||||
// 监听只读
|
||||
watch(() => props.readonly, () => {
|
||||
if (editor) {
|
||||
editor.updateOptions({ readOnly: props.readonly });
|
||||
}
|
||||
});
|
||||
|
||||
// 修改语言
|
||||
watch(() => props.language, (v) => {
|
||||
if (editor) {
|
||||
monaco.editor.setModelLanguage(editor?.getModel(), v as string);
|
||||
}
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
init();
|
||||
});
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
editor?.dispose();
|
||||
editor = undefined;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.editor-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,38 @@
|
||||
// 代码提示
|
||||
monaco.languages.registerCompletionItemProvider('java', {
|
||||
provideCompletionItems() {
|
||||
const suggestions: any = [];
|
||||
// 这个keywords就是java.java文件中有的
|
||||
javaLanguage.keywords?.forEach((item: any) => {
|
||||
suggestions.push({
|
||||
label: item,
|
||||
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||
insertText: item,
|
||||
});
|
||||
});
|
||||
javaLanguage.operators?.forEach((item: any) => {
|
||||
suggestions.push({
|
||||
label: item,
|
||||
kind: monaco.languages.CompletionItemKind.Operator,
|
||||
insertText: item,
|
||||
});
|
||||
});
|
||||
javaLanguage.builtinFunctions?.forEach((item: any) => {
|
||||
suggestions.push({
|
||||
label: item,
|
||||
kind: monaco.languages.CompletionItemKind.Function,
|
||||
insertText: item,
|
||||
});
|
||||
});
|
||||
javaLanguage.builtinVariables?.forEach((item: any) => {
|
||||
suggestions.push({
|
||||
label: item,
|
||||
kind: monaco.languages.CompletionItemKind.Variable,
|
||||
insertText: item,
|
||||
});
|
||||
});
|
||||
return {
|
||||
suggestions,
|
||||
};
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user