feat(代码编辑器): 代码自动格式化
This commit is contained in:
parent
9b2c2552ce
commit
e0cbf9ae2a
|
@ -82,35 +82,8 @@
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
// 编辑器实例,每次调用组件都会创建独立的实例
|
// 编辑器实例,每次调用组件都会创建独立的实例
|
||||||
let editor: monaco.editor.IStandaloneCodeEditor;
|
let editor: monaco.editor.IStandaloneCodeEditor;
|
||||||
|
|
||||||
const codeContainerRef = ref();
|
const codeContainerRef = ref();
|
||||||
|
|
||||||
const init = () => {
|
|
||||||
// 注册自定义主题 TODO:自定义主题高亮色还没配置
|
|
||||||
Object.keys(MsCodeEditorTheme).forEach((e) => {
|
|
||||||
monaco.editor.defineTheme(e, MsCodeEditorTheme[e as CustomTheme]);
|
|
||||||
});
|
|
||||||
editor = monaco.editor.create(codeContainerRef.value, {
|
|
||||||
value: props.modelValue,
|
|
||||||
automaticLayout: true,
|
|
||||||
padding: {
|
|
||||||
top: 12,
|
|
||||||
bottom: 12,
|
|
||||||
},
|
|
||||||
minimap: {
|
|
||||||
enabled: false, // 将代码块预览隐藏
|
|
||||||
},
|
|
||||||
...props,
|
|
||||||
});
|
|
||||||
|
|
||||||
// 监听值的变化
|
|
||||||
editor.onDidChangeModelContent(() => {
|
|
||||||
const value = editor.getValue(); // 给父组件实时返回最新文本
|
|
||||||
emit('update:modelValue', value);
|
|
||||||
emit('change', value);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 用于全屏的容器 ref
|
// 用于全屏的容器 ref
|
||||||
const fullRef = ref<HTMLElement | null>();
|
const fullRef = ref<HTMLElement | null>();
|
||||||
// 当前主题
|
// 当前主题
|
||||||
|
@ -235,12 +208,49 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function format() {
|
function format() {
|
||||||
if (editor) {
|
if (editor && editor.getValue() !== '' && props.language !== LanguageEnum.PLAINTEXT) {
|
||||||
// 格式化代码 TODO:需要额外的格式化插件或编写格式化配置
|
editor.updateOptions({ readOnly: false });
|
||||||
editor.getAction('editor.action.formatDocument')?.run();
|
// 执行格式化代码的动作
|
||||||
|
editor
|
||||||
|
.getAction('editor.action.formatDocument')
|
||||||
|
?.run()
|
||||||
|
.then(() => {
|
||||||
|
const value = editor.getValue(); // 给父组件实时返回最新文本
|
||||||
|
editor.updateOptions({ readOnly: true });
|
||||||
|
emit('update:modelValue', value);
|
||||||
|
emit('change', value);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const init = () => {
|
||||||
|
// 注册自定义主题 TODO:自定义主题高亮色还没配置
|
||||||
|
Object.keys(MsCodeEditorTheme).forEach((e) => {
|
||||||
|
monaco.editor.defineTheme(e, MsCodeEditorTheme[e as CustomTheme]);
|
||||||
|
});
|
||||||
|
editor = monaco.editor.create(codeContainerRef.value, {
|
||||||
|
value: props.modelValue,
|
||||||
|
automaticLayout: true,
|
||||||
|
padding: {
|
||||||
|
top: 12,
|
||||||
|
bottom: 12,
|
||||||
|
},
|
||||||
|
minimap: {
|
||||||
|
enabled: false, // 将代码块预览隐藏
|
||||||
|
},
|
||||||
|
contextmenu: !props.readOnly, // 只读模式下禁用右键菜单
|
||||||
|
...props,
|
||||||
|
language: props.language.toLowerCase(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听值的变化
|
||||||
|
editor.onDidChangeModelContent(() => {
|
||||||
|
const value = editor.getValue(); // 给父组件实时返回最新文本
|
||||||
|
emit('update:modelValue', value);
|
||||||
|
emit('change', value);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => props.modelValue,
|
() => props.modelValue,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
|
@ -250,7 +260,8 @@
|
||||||
editor.setValue(newValue);
|
editor.setValue(newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
{ immediate: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
@ -264,6 +275,7 @@
|
||||||
watch(
|
watch(
|
||||||
() => props.language,
|
() => props.language,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
|
currentLanguage.value = newValue;
|
||||||
monaco.editor.setModelLanguage(editor.getModel()!, newValue.toLowerCase()); // 设置语言,语言 ENUM 是大写的,但是 monaco 需要小写
|
monaco.editor.setModelLanguage(editor.getModel()!, newValue.toLowerCase()); // 设置语言,语言 ENUM 是大写的,但是 monaco 需要小写
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -275,6 +287,17 @@
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
init();
|
init();
|
||||||
setEditBoxBg();
|
setEditBoxBg();
|
||||||
|
if (props.readOnly) {
|
||||||
|
format();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
onUpdated(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (props.readOnly) {
|
||||||
|
format();
|
||||||
|
}
|
||||||
|
}, 100); // TODO:暂未找到准确的格式化时机
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -121,12 +121,14 @@
|
||||||
activeLayout === 'horizontal' ? ' pr-[16px]' : ''
|
activeLayout === 'horizontal' ? ' pr-[16px]' : ''
|
||||||
}`"
|
}`"
|
||||||
>
|
>
|
||||||
|
<div>
|
||||||
<MsTab
|
<MsTab
|
||||||
v-model:active-key="requestVModel.activeTab"
|
v-model:active-key="requestVModel.activeTab"
|
||||||
:content-tab-list="contentTabList"
|
:content-tab-list="contentTabList"
|
||||||
:get-text-func="getTabBadge"
|
:get-text-func="getTabBadge"
|
||||||
class="no-content relative mb-[8px] border-b border-[var(--color-text-n8)]"
|
class="no-content relative mb-[8px] border-b border-[var(--color-text-n8)]"
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
<div class="tab-pane-container">
|
<div class="tab-pane-container">
|
||||||
<template v-if="requestVModel.activeTab === RequestComposition.PLUGIN || isInitPluginForm">
|
<template v-if="requestVModel.activeTab === RequestComposition.PLUGIN || isInitPluginForm">
|
||||||
<a-spin
|
<a-spin
|
||||||
|
|
|
@ -109,7 +109,7 @@
|
||||||
<MsCodeEditor
|
<MsCodeEditor
|
||||||
v-if="activeTab === ResponseComposition.BODY"
|
v-if="activeTab === ResponseComposition.BODY"
|
||||||
ref="responseEditorRef"
|
ref="responseEditorRef"
|
||||||
:model-value="props.response.requestResults[0]?.responseResult?.body || ''"
|
:model-value="props.response.requestResults[0]?.responseResult?.body"
|
||||||
:language="responseLanguage"
|
:language="responseLanguage"
|
||||||
theme="vs"
|
theme="vs"
|
||||||
height="100%"
|
height="100%"
|
||||||
|
@ -130,7 +130,6 @@
|
||||||
</MsCodeEditor>
|
</MsCodeEditor>
|
||||||
<MsCodeEditor
|
<MsCodeEditor
|
||||||
v-else-if="activeTab === ResponseComposition.CONSOLE"
|
v-else-if="activeTab === ResponseComposition.CONSOLE"
|
||||||
ref="responseEditorRef"
|
|
||||||
:model-value="response.console.trim()"
|
:model-value="response.console.trim()"
|
||||||
:language="LanguageEnum.PLAINTEXT"
|
:language="LanguageEnum.PLAINTEXT"
|
||||||
theme="MS-text"
|
theme="MS-text"
|
||||||
|
@ -284,17 +283,6 @@
|
||||||
});
|
});
|
||||||
const responseEditorRef = ref<InstanceType<typeof MsCodeEditor>>();
|
const responseEditorRef = ref<InstanceType<typeof MsCodeEditor>>();
|
||||||
|
|
||||||
watch(
|
|
||||||
() => props.response,
|
|
||||||
(obj) => {
|
|
||||||
if (obj.requestResults[0].responseResult.body.trim() !== '') {
|
|
||||||
nextTick(() => {
|
|
||||||
responseEditorRef.value?.format();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const responseTabList = [
|
const responseTabList = [
|
||||||
{
|
{
|
||||||
label: t('apiTestDebug.responseBody'),
|
label: t('apiTestDebug.responseBody'),
|
||||||
|
|
Loading…
Reference in New Issue