mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-03-30 09:10:45 +00:00
feat(editor): monaco-editor改成异步加载
This commit is contained in:
parent
0d698b20e7
commit
71d6dd9e38
@ -54,7 +54,7 @@
|
|||||||
"@tmagic/utils": "workspace:*",
|
"@tmagic/utils": "workspace:*",
|
||||||
"buffer": "^6.0.3",
|
"buffer": "^6.0.3",
|
||||||
"deep-object-diff": "^1.1.9",
|
"deep-object-diff": "^1.1.9",
|
||||||
"emmet-monaco-es": "^5.6.1",
|
"emmet-monaco-es": "^5.7.0",
|
||||||
"events": "^3.3.0",
|
"events": "^3.3.0",
|
||||||
"gesto": "^1.19.4",
|
"gesto": "^1.19.4",
|
||||||
"keycon": "^1.4.0",
|
"keycon": "^1.4.0",
|
||||||
|
|||||||
@ -20,13 +20,14 @@
|
|||||||
import { computed, nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, useTemplateRef, watch } from 'vue';
|
import { computed, nextTick, onBeforeUnmount, onMounted, onUnmounted, ref, useTemplateRef, watch } from 'vue';
|
||||||
import { FullScreen } from '@element-plus/icons-vue';
|
import { FullScreen } from '@element-plus/icons-vue';
|
||||||
import { throttle } from 'lodash-es';
|
import { throttle } from 'lodash-es';
|
||||||
|
import type * as Monaco from 'monaco-editor';
|
||||||
import serialize from 'serialize-javascript';
|
import serialize from 'serialize-javascript';
|
||||||
|
|
||||||
import { TMagicButton } from '@tmagic/design';
|
import { TMagicButton } from '@tmagic/design';
|
||||||
|
|
||||||
import MIcon from '@editor/components/Icon.vue';
|
import MIcon from '@editor/components/Icon.vue';
|
||||||
import { getEditorConfig } from '@editor/utils/config';
|
import { getEditorConfig } from '@editor/utils/config';
|
||||||
import monaco from '@editor/utils/monaco-editor';
|
import loadMonaco from '@editor/utils/monaco-editor';
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'MEditorCodeEditor',
|
name: 'MEditorCodeEditor',
|
||||||
@ -38,7 +39,7 @@ const props = withDefaults(
|
|||||||
modifiedValues?: any;
|
modifiedValues?: any;
|
||||||
type?: 'diff';
|
type?: 'diff';
|
||||||
language?: string;
|
language?: string;
|
||||||
options?: monaco.editor.IStandaloneEditorConstructionOptions;
|
options?: Monaco.editor.IStandaloneEditorConstructionOptions;
|
||||||
height?: string;
|
height?: string;
|
||||||
autoSave?: boolean;
|
autoSave?: boolean;
|
||||||
parse?: boolean;
|
parse?: boolean;
|
||||||
@ -99,7 +100,7 @@ const calculateExtraHeight = (): number => {
|
|||||||
extraHeight = Math.max(editorRect.height - scrollableRect.height, 0);
|
extraHeight = Math.max(editorRect.height - scrollableRect.height, 0);
|
||||||
|
|
||||||
// 如果无法获取到有效的差值,使用编辑器配置中的相关选项
|
// 如果无法获取到有效的差值,使用编辑器配置中的相关选项
|
||||||
if (extraHeight === 0) {
|
if (extraHeight === 0 && monaco) {
|
||||||
const editorOptions = vsEditor.getOptions();
|
const editorOptions = vsEditor.getOptions();
|
||||||
const scrollBeyondLastLine = editorOptions.get(monaco.editor.EditorOption.scrollBeyondLastLine);
|
const scrollBeyondLastLine = editorOptions.get(monaco.editor.EditorOption.scrollBeyondLastLine);
|
||||||
const padding = editorOptions.get(monaco.editor.EditorOption.padding);
|
const padding = editorOptions.get(monaco.editor.EditorOption.padding);
|
||||||
@ -127,7 +128,7 @@ const setAutoHeight = (v = '') => {
|
|||||||
|
|
||||||
// 获取编辑器实际行高,如果编辑器还未初始化则使用默认值
|
// 获取编辑器实际行高,如果编辑器还未初始化则使用默认值
|
||||||
let lineHeight = 20;
|
let lineHeight = 20;
|
||||||
if (vsEditor) {
|
if (vsEditor && monaco) {
|
||||||
const editorOptions = vsEditor.getOptions();
|
const editorOptions = vsEditor.getOptions();
|
||||||
lineHeight = editorOptions.get(monaco.editor.EditorOption.lineHeight) || 20;
|
lineHeight = editorOptions.get(monaco.editor.EditorOption.lineHeight) || 20;
|
||||||
}
|
}
|
||||||
@ -188,8 +189,9 @@ const parseCode = (v: string | any, language: string): any => {
|
|||||||
return getEditorConfig('parseDSL')(v);
|
return getEditorConfig('parseDSL')(v);
|
||||||
};
|
};
|
||||||
|
|
||||||
let vsEditor: monaco.editor.IStandaloneCodeEditor | null = null;
|
let monaco: typeof import('monaco-editor') | null = null;
|
||||||
let vsDiffEditor: monaco.editor.IStandaloneDiffEditor | null = null;
|
let vsEditor: Monaco.editor.IStandaloneCodeEditor | null = null;
|
||||||
|
let vsDiffEditor: Monaco.editor.IStandaloneDiffEditor | null = null;
|
||||||
|
|
||||||
const values = ref('');
|
const values = ref('');
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
@ -207,6 +209,8 @@ const setEditorValue = (v: string | any, m: string | any) => {
|
|||||||
|
|
||||||
setAutoHeight(values.value);
|
setAutoHeight(values.value);
|
||||||
|
|
||||||
|
if (!monaco) return;
|
||||||
|
|
||||||
if (props.type === 'diff') {
|
if (props.type === 'diff') {
|
||||||
const originalModel = monaco.editor.createModel(values.value, 'text/javascript');
|
const originalModel = monaco.editor.createModel(values.value, 'text/javascript');
|
||||||
const modifiedModel = monaco.editor.createModel(toString(m, props.language), 'text/javascript');
|
const modifiedModel = monaco.editor.createModel(toString(m, props.language), 'text/javascript');
|
||||||
@ -255,6 +259,8 @@ const init = async () => {
|
|||||||
// 重置缓存的额外高度,因为编辑器重新初始化
|
// 重置缓存的额外高度,因为编辑器重新初始化
|
||||||
cachedExtraHeight = null;
|
cachedExtraHeight = null;
|
||||||
|
|
||||||
|
monaco = await loadMonaco();
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
value: values.value,
|
value: values.value,
|
||||||
language: props.language,
|
language: props.language,
|
||||||
@ -264,7 +270,7 @@ const init = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (props.type === 'diff') {
|
if (props.type === 'diff') {
|
||||||
vsDiffEditor = getEditorConfig('customCreateMonacoDiffEditor')(monaco, codeEditorEl.value, options);
|
vsDiffEditor = await getEditorConfig('customCreateMonacoDiffEditor')(monaco!, codeEditorEl.value, options);
|
||||||
|
|
||||||
// 监听diff编辑器内容变化
|
// 监听diff编辑器内容变化
|
||||||
vsDiffEditor.getModifiedEditor().onDidChangeModelContent(() => {
|
vsDiffEditor.getModifiedEditor().onDidChangeModelContent(() => {
|
||||||
@ -274,7 +280,7 @@ const init = async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
vsEditor = getEditorConfig('customCreateMonacoEditor')(monaco, codeEditorEl.value, options);
|
vsEditor = await getEditorConfig('customCreateMonacoEditor')(monaco!, codeEditorEl.value, options);
|
||||||
|
|
||||||
// 监听编辑器内容变化
|
// 监听编辑器内容变化
|
||||||
vsEditor.onDidChangeModelContent(() => {
|
vsEditor.onDidChangeModelContent(() => {
|
||||||
@ -343,6 +349,7 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
vsEditor = null;
|
vsEditor = null;
|
||||||
vsDiffEditor = null;
|
vsDiffEditor = null;
|
||||||
|
monaco = null;
|
||||||
|
|
||||||
// 重置缓存
|
// 重置缓存
|
||||||
cachedExtraHeight = null;
|
cachedExtraHeight = null;
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
import type { Component } from 'vue';
|
import type { Component } from 'vue';
|
||||||
import type EventEmitter from 'events';
|
import type EventEmitter from 'events';
|
||||||
|
import type * as Monaco from 'monaco-editor';
|
||||||
import Sortable, { type Options, type SortableEvent } from 'sortablejs';
|
import Sortable, { type Options, type SortableEvent } from 'sortablejs';
|
||||||
import type { PascalCasedProperties } from 'type-fest';
|
import type { PascalCasedProperties } from 'type-fest';
|
||||||
|
|
||||||
@ -32,8 +33,6 @@ import type {
|
|||||||
UpdateDragEl,
|
UpdateDragEl,
|
||||||
} from '@tmagic/stage';
|
} from '@tmagic/stage';
|
||||||
|
|
||||||
import Monaco from '@editor/utils/monaco-editor';
|
|
||||||
|
|
||||||
import type { CodeBlockService } from './services/codeBlock';
|
import type { CodeBlockService } from './services/codeBlock';
|
||||||
import type { ComponentListService } from './services/componentList';
|
import type { ComponentListService } from './services/componentList';
|
||||||
import type { DataSourceService } from './services/dataSource';
|
import type { DataSourceService } from './services/dataSource';
|
||||||
@ -121,15 +120,15 @@ export type GetConfig = (config: FormConfig) => Promise<FormConfig> | FormConfig
|
|||||||
export interface EditorInstallOptions {
|
export interface EditorInstallOptions {
|
||||||
parseDSL: <T = any>(dsl: string) => T;
|
parseDSL: <T = any>(dsl: string) => T;
|
||||||
customCreateMonacoEditor: (
|
customCreateMonacoEditor: (
|
||||||
monaco: typeof Monaco,
|
monaco: typeof import('monaco-editor'),
|
||||||
codeEditorEl: HTMLElement,
|
codeEditorEl: HTMLElement,
|
||||||
options: Monaco.editor.IStandaloneEditorConstructionOptions & { editorCustomType?: string },
|
options: Monaco.editor.IStandaloneEditorConstructionOptions & { editorCustomType?: string },
|
||||||
) => Monaco.editor.IStandaloneCodeEditor;
|
) => Promise<Monaco.editor.IStandaloneCodeEditor> | Monaco.editor.IStandaloneCodeEditor;
|
||||||
customCreateMonacoDiffEditor: (
|
customCreateMonacoDiffEditor: (
|
||||||
monaco: typeof Monaco,
|
monaco: typeof import('monaco-editor'),
|
||||||
codeEditorEl: HTMLElement,
|
codeEditorEl: HTMLElement,
|
||||||
options: Monaco.editor.IStandaloneEditorConstructionOptions & { editorCustomType?: string },
|
options: Monaco.editor.IStandaloneEditorConstructionOptions & { editorCustomType?: string },
|
||||||
) => Monaco.editor.IStandaloneDiffEditor;
|
) => Promise<Monaco.editor.IStandaloneDiffEditor> | Monaco.editor.IStandaloneDiffEditor;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,15 @@
|
|||||||
import { emmetCSS, emmetHTML } from 'emmet-monaco-es';
|
let cached: Promise<typeof import('monaco-editor')> | undefined;
|
||||||
import * as monaco from 'monaco-editor';
|
|
||||||
|
|
||||||
// 注册emmet插件
|
export default () => {
|
||||||
|
if (!cached) {
|
||||||
|
cached = Promise.all([import('emmet-monaco-es'), import('monaco-editor')]).then(([emmet, monaco]) => {
|
||||||
|
const { emmetHTML, emmetCSS } = emmet;
|
||||||
emmetHTML(monaco);
|
emmetHTML(monaco);
|
||||||
emmetCSS(monaco, ['css', 'scss']);
|
emmetCSS(monaco, ['css', 'scss']);
|
||||||
|
|
||||||
export default monaco;
|
return monaco;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return cached;
|
||||||
|
};
|
||||||
|
|||||||
@ -47,6 +47,7 @@ export const numberOptions = [
|
|||||||
|
|
||||||
export const styleTabConfig: TabPaneConfig = {
|
export const styleTabConfig: TabPaneConfig = {
|
||||||
title: '样式',
|
title: '样式',
|
||||||
|
lazy: true,
|
||||||
display: ({ services }: any) => !(services.uiService.get('showStylePanel') ?? true),
|
display: ({ services }: any) => !(services.uiService.get('showStylePanel') ?? true),
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
@ -114,6 +115,7 @@ export const styleTabConfig: TabPaneConfig = {
|
|||||||
|
|
||||||
export const eventTabConfig: TabPaneConfig = {
|
export const eventTabConfig: TabPaneConfig = {
|
||||||
title: '事件',
|
title: '事件',
|
||||||
|
lazy: true,
|
||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
name: 'events',
|
name: 'events',
|
||||||
|
|||||||
16
pnpm-lock.yaml
generated
16
pnpm-lock.yaml
generated
@ -327,8 +327,8 @@ importers:
|
|||||||
specifier: ^1.1.9
|
specifier: ^1.1.9
|
||||||
version: 1.1.9
|
version: 1.1.9
|
||||||
emmet-monaco-es:
|
emmet-monaco-es:
|
||||||
specifier: ^5.6.1
|
specifier: ^5.7.0
|
||||||
version: 5.6.1(monaco-editor@0.48.0)
|
version: 5.7.0(monaco-editor@0.48.0)
|
||||||
events:
|
events:
|
||||||
specifier: ^3.3.0
|
specifier: ^3.3.0
|
||||||
version: 3.3.0
|
version: 3.3.0
|
||||||
@ -4166,8 +4166,8 @@ packages:
|
|||||||
peerDependencies:
|
peerDependencies:
|
||||||
vue: ^3.2.0
|
vue: ^3.2.0
|
||||||
|
|
||||||
emmet-monaco-es@5.6.1:
|
emmet-monaco-es@5.7.0:
|
||||||
resolution: {integrity: sha512-Bdh0CJaG2NvcwCgRYQMBqtIiDI9/BwYNTFUnYd68OXC8DXNcAVLsIKIEnDhOGYtEO60Knf2OgMrL7UDQ5zh1yA==}
|
resolution: {integrity: sha512-q8jtgsEWWaXHnAJ6HAcwMB7WHraRtf032TWpeOpN6SGLtwxr7hd6RgF3Kbj2rPxb6Q19fYVVafAFODYRYUS8NQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
monaco-editor: '>=0.22.0'
|
monaco-editor: '>=0.22.0'
|
||||||
|
|
||||||
@ -8380,7 +8380,7 @@ snapshots:
|
|||||||
'@tmagic/utils': 1.7.2(@tmagic/schema@1.7.6(typescript@5.9.3))(typescript@5.9.3)
|
'@tmagic/utils': 1.7.2(@tmagic/schema@1.7.6(typescript@5.9.3))(typescript@5.9.3)
|
||||||
buffer: 6.0.3
|
buffer: 6.0.3
|
||||||
deep-object-diff: 1.1.9
|
deep-object-diff: 1.1.9
|
||||||
emmet-monaco-es: 5.6.1(monaco-editor@0.55.1)
|
emmet-monaco-es: 5.7.0(monaco-editor@0.55.1)
|
||||||
events: 3.3.0
|
events: 3.3.0
|
||||||
gesto: 1.19.4
|
gesto: 1.19.4
|
||||||
keycon: 1.4.0
|
keycon: 1.4.0
|
||||||
@ -8407,7 +8407,7 @@ snapshots:
|
|||||||
'@tmagic/utils': 1.7.6(@tmagic/schema@1.7.6(typescript@5.9.3))(typescript@5.9.3)
|
'@tmagic/utils': 1.7.6(@tmagic/schema@1.7.6(typescript@5.9.3))(typescript@5.9.3)
|
||||||
buffer: 6.0.3
|
buffer: 6.0.3
|
||||||
deep-object-diff: 1.1.9
|
deep-object-diff: 1.1.9
|
||||||
emmet-monaco-es: 5.6.1(monaco-editor@0.55.1)
|
emmet-monaco-es: 5.7.0(monaco-editor@0.55.1)
|
||||||
events: 3.3.0
|
events: 3.3.0
|
||||||
gesto: 1.19.4
|
gesto: 1.19.4
|
||||||
keycon: 1.4.0
|
keycon: 1.4.0
|
||||||
@ -9848,12 +9848,12 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
|
|
||||||
emmet-monaco-es@5.6.1(monaco-editor@0.48.0):
|
emmet-monaco-es@5.7.0(monaco-editor@0.48.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
emmet: 2.4.11
|
emmet: 2.4.11
|
||||||
monaco-editor: 0.48.0
|
monaco-editor: 0.48.0
|
||||||
|
|
||||||
emmet-monaco-es@5.6.1(monaco-editor@0.55.1):
|
emmet-monaco-es@5.7.0(monaco-editor@0.55.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
emmet: 2.4.11
|
emmet: 2.4.11
|
||||||
monaco-editor: 0.55.1
|
monaco-editor: 0.55.1
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user