添加 editor.

This commit is contained in:
lijiahang
2023-10-26 14:10:48 +08:00
parent d3825ab5b2
commit 03e18cc0e2
9 changed files with 327 additions and 16380 deletions

View File

@@ -48,4 +48,14 @@ export default defineConfig({
},
},
},
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`
],
},
});

File diff suppressed because it is too large Load Diff

View File

@@ -38,6 +38,7 @@
"echarts": "^5.4.0",
"lodash": "^4.17.21",
"mitt": "^3.0.0",
"monaco-editor": "^0.44.0",
"nprogress": "^0.2.0",
"pinia": "^2.0.23",
"query-string": "^8.0.3",
@@ -77,6 +78,7 @@
"prettier": "^2.7.1",
"rollup": "^3.9.1",
"rollup-plugin-visualizer": "^5.8.2",
"sass": "^1.69.4",
"stylelint": "^14.13.0",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-rational-order": "^0.1.2",

View File

@@ -37,6 +37,9 @@ dependencies:
mitt:
specifier: ^3.0.0
version: 3.0.1
monaco-editor:
specifier: ^0.44.0
version: 0.44.0
nprogress:
specifier: ^0.2.0
version: 0.2.0
@@ -150,6 +153,9 @@ devDependencies:
rollup-plugin-visualizer:
specifier: ^5.8.2
version: 5.9.2(rollup@2.79.1)
sass:
specifier: ^1.69.4
version: 1.69.4
stylelint:
specifier: ^14.13.0
version: 14.16.1
@@ -176,7 +182,7 @@ devDependencies:
version: 0.24.1(rollup@2.79.1)(vue@3.3.4)
vite:
specifier: ^3.2.5
version: 3.2.7(@types/node@20.4.7)(less@4.2.0)
version: 3.2.7(@types/node@20.4.7)(less@4.2.0)(sass@1.69.4)
vite-plugin-compression:
specifier: ^0.5.1
version: 0.5.1(vite@3.2.7)
@@ -1269,7 +1275,7 @@ packages:
'@babel/core': 7.22.19
'@babel/plugin-transform-typescript': 7.22.15(@babel/core@7.22.19)
'@vue/babel-plugin-jsx': 1.1.5(@babel/core@7.22.19)
vite: 3.2.7(@types/node@20.4.7)(less@4.2.0)
vite: 3.2.7(@types/node@20.4.7)(less@4.2.0)(sass@1.69.4)
vue: 3.3.4
transitivePeerDependencies:
- supports-color
@@ -1282,7 +1288,7 @@ packages:
vite: ^3.0.0
vue: ^3.2.25
dependencies:
vite: 3.2.7(@types/node@20.4.7)(less@4.2.0)
vite: 3.2.7(@types/node@20.4.7)(less@4.2.0)(sass@1.69.4)
vue: 3.3.4
dev: true
@@ -4697,6 +4703,10 @@ packages:
replace-ext: 1.0.1
dev: true
/immutable@4.3.4:
resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==}
dev: true
/import-fresh@2.0.0:
resolution: {integrity: sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==}
engines: {node: '>=4'}
@@ -5902,6 +5912,10 @@ packages:
commander: 11.0.0
dev: true
/monaco-editor@0.44.0:
resolution: {integrity: sha512-5SmjNStN6bSuSE5WPT2ZV+iYn1/yI9sd4Igtk23ChvqB7kDk9lZbB9F5frsuvpB+2njdIeGGFf2G4gbE6rCC9Q==}
dev: false
/mozjpeg@7.1.1:
resolution: {integrity: sha512-iIDxWvzhWvLC9mcRJ1uSkiKaj4drF58oCqK2bITm5c2Jt6cJ8qQjSSru2PCaysG+hLIinryj8mgz5ZJzOYTv1A==}
engines: {node: '>=10'}
@@ -7187,6 +7201,16 @@ packages:
dev: true
optional: true
/sass@1.69.4:
resolution: {integrity: sha512-+qEreVhqAy8o++aQfCJwp0sklr2xyEzkm9Pp/Igu9wNPoe7EZEQ8X/MBvvXggI2ql607cxKg/RKOwDj6pp2XDA==}
engines: {node: '>=14.0.0'}
hasBin: true
dependencies:
chokidar: 3.5.3
immutable: 4.3.4
source-map-js: 1.0.2
dev: true
/sax@1.2.4:
resolution: {integrity: sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==}
requiresBuild: true
@@ -8484,7 +8508,7 @@ packages:
chalk: 4.1.2
debug: 4.3.4
fs-extra: 10.1.0
vite: 3.2.7(@types/node@20.4.7)(less@4.2.0)
vite: 3.2.7(@types/node@20.4.7)(less@4.2.0)(sass@1.69.4)
transitivePeerDependencies:
- supports-color
dev: true
@@ -8499,7 +8523,7 @@ packages:
'@types/eslint': 8.44.2
eslint: 8.49.0
rollup: 2.79.1
vite: 3.2.7(@types/node@20.4.7)(less@4.2.0)
vite: 3.2.7(@types/node@20.4.7)(less@4.2.0)(sass@1.69.4)
dev: true
/vite-plugin-imagemin@0.6.1(vite@3.2.7):
@@ -8530,7 +8554,7 @@ packages:
imagemin-webp: 6.1.0
jpegtran-bin: 6.0.1
pathe: 0.2.0
vite: 3.2.7(@types/node@20.4.7)(less@4.2.0)
vite: 3.2.7(@types/node@20.4.7)(less@4.2.0)(sass@1.69.4)
transitivePeerDependencies:
- supports-color
dev: true
@@ -8542,7 +8566,7 @@ packages:
svgo: 2.8.0
dev: true
/vite@3.2.7(@types/node@20.4.7)(less@4.2.0):
/vite@3.2.7(@types/node@20.4.7)(less@4.2.0)(sass@1.69.4):
resolution: {integrity: sha512-29pdXjk49xAP0QBr0xXqu2s5jiQIXNvE/xwd0vUizYT2Hzqe4BksNNoWllFVXJf4eLZ+UlVQmXfB4lWrc+t18g==}
engines: {node: ^14.18.0 || >=16.0.0}
hasBin: true
@@ -8573,6 +8597,7 @@ packages:
postcss: 8.4.29
resolve: 1.22.5
rollup: 2.79.1
sass: 1.69.4
optionalDependencies:
fsevents: 2.3.3
dev: true

View 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();
},
};

View 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>

View File

@@ -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,
};
},
});

View File

@@ -6,6 +6,13 @@ declare module '*.vue' {
const component: DefineComponent<{}, {}, any>;
export default component;
}
interface ImportMetaEnv {
readonly VITE_API_BASE_URL: string;
}
// editor
declare module 'monaco-editor';
declare module 'monaco-editor/esm/vs/editor/editor.worker?worker'
declare module 'monaco-editor/esm/vs/language/json/json.worker?worker'
declare module 'monaco-editor/esm/vs/basic-languages/yaml/yaml.js';

View File

@@ -2,12 +2,12 @@
<div class="layout-container">
<!-- 列表-表格 -->
<dict-key-table ref="table"
@openAdd="() => modal.openAdd()"
@openUpdate="(e) => modal.openUpdate(e)" />
@openAdd="() => modal.openAdd()"
@openUpdate="(e) => modal.openUpdate(e)" />
<!-- 添加修改模态框 -->
<dict-key-form-modal ref="modal"
@added="modalAddCallback"
@updated="modalUpdateCallback" />
@added="modalAddCallback"
@updated="modalUpdateCallback" />
</div>
</template>
@@ -18,11 +18,10 @@
</script>
<script lang="ts" setup>
import { ref } from 'vue';
import DictKeyTable from './components/dict-key-table.vue';
import DictKeyFormModal from './components/dict-key-form-modal.vue';
import { ref } from 'vue';
const table = ref();
const modal = ref();