mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-12-12 03:02:50 +00:00
199 lines
4.7 KiB
Vue
199 lines
4.7 KiB
Vue
<template>
|
|
<div class="editor-app">
|
|
<m-editor
|
|
v-model="value"
|
|
ref="editor"
|
|
:menu="menu"
|
|
:runtime-url="runtimeUrl"
|
|
:props-configs="propsConfigs"
|
|
:props-values="propsValues"
|
|
:event-method-list="eventMethodList"
|
|
:component-group-list="componentGroupList"
|
|
:default-selected="defaultSelected"
|
|
:moveable-options="moveableOptions"
|
|
></m-editor>
|
|
|
|
<el-dialog v-model="previewVisible" destroy-on-close :width="375" custom-class="pre-viewer" title="预览">
|
|
<iframe
|
|
v-if="previewVisible"
|
|
width="100%"
|
|
height="817"
|
|
:src="`${RUNTIME_PATH}/page.html?localPreview=1&page=${editor?.editorService.get('page').id}`"
|
|
></iframe>
|
|
</el-dialog>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { defineComponent, ref, toRaw } from 'vue';
|
|
import { Coin, Connection, Document, FolderOpened, SwitchButton, Tickets } from '@element-plus/icons';
|
|
import { ElMessage } from 'element-plus';
|
|
import serialize from 'serialize-javascript';
|
|
|
|
import type { MenuBarData, MoveableOptions, TMagicEditor } from '@tmagic/editor';
|
|
import StageCore from '@tmagic/stage';
|
|
import { asyncLoadJs } from '@tmagic/utils';
|
|
|
|
import config from '../config';
|
|
|
|
const RUNTIME_PATH = '/tmagic-editor/playground/runtime/vue3';
|
|
|
|
export default defineComponent({
|
|
name: 'EditorApp',
|
|
|
|
setup() {
|
|
const editor = ref<InstanceType<typeof TMagicEditor>>();
|
|
const previewVisible = ref(false);
|
|
const value = ref(config);
|
|
const defaultSelected = ref(config.items[0].id);
|
|
const propsValues = ref<Record<string, any>>({});
|
|
const propsConfigs = ref<Record<string, any>>({});
|
|
const eventMethodList = ref<Record<string, any>>({});
|
|
const menu: MenuBarData = {
|
|
left: [
|
|
{
|
|
type: 'text',
|
|
text: '魔方',
|
|
},
|
|
],
|
|
center: ['delete', 'undo', 'redo', 'guides', 'rule', 'zoom'],
|
|
right: [
|
|
{
|
|
type: 'button',
|
|
text: '预览',
|
|
icon: Connection,
|
|
handler: () => {
|
|
previewVisible.value = true;
|
|
},
|
|
},
|
|
{
|
|
type: 'button',
|
|
text: '保存',
|
|
icon: Coin,
|
|
handler: (service) => {
|
|
localStorage.setItem(
|
|
'magicUiConfig',
|
|
serialize(toRaw(value.value), {
|
|
space: 2,
|
|
unsafe: true,
|
|
}).replace(/"(\w+)":\s/g, '$1: '),
|
|
);
|
|
service?.editorService.resetModifiedNodeId();
|
|
ElMessage.success('保存成功');
|
|
},
|
|
},
|
|
'/',
|
|
{
|
|
type: 'button',
|
|
icon: Document,
|
|
tooltip: '源码',
|
|
handler: (service) => service?.uiService.set('showSrc', !service?.uiService.get('showSrc')),
|
|
},
|
|
],
|
|
};
|
|
|
|
asyncLoadJs(`${RUNTIME_PATH}/assets/config.js`).then(() => {
|
|
propsConfigs.value = (globalThis as any).magicPresetConfigs;
|
|
});
|
|
asyncLoadJs(`${RUNTIME_PATH}/assets/value.js`).then(() => {
|
|
propsValues.value = (globalThis as any).magicPresetValues;
|
|
});
|
|
asyncLoadJs(`${RUNTIME_PATH}/assets/event.js`).then(() => {
|
|
eventMethodList.value = (globalThis as any).magicPresetEvents;
|
|
});
|
|
|
|
return {
|
|
RUNTIME_PATH,
|
|
|
|
editor,
|
|
menu,
|
|
value,
|
|
defaultSelected,
|
|
propsValues,
|
|
propsConfigs,
|
|
eventMethodList,
|
|
|
|
previewVisible,
|
|
|
|
runtimeUrl: `${RUNTIME_PATH}/playground.html`,
|
|
|
|
componentGroupList: ref([
|
|
{
|
|
title: '示例容器',
|
|
items: [
|
|
{
|
|
icon: FolderOpened,
|
|
text: '组',
|
|
type: 'container',
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: '示例组件',
|
|
items: [
|
|
{
|
|
icon: Tickets,
|
|
text: '文本',
|
|
type: 'text',
|
|
},
|
|
{
|
|
icon: SwitchButton,
|
|
text: '按钮',
|
|
type: 'button',
|
|
},
|
|
],
|
|
},
|
|
]),
|
|
|
|
moveableOptions: (core?: StageCore): MoveableOptions => {
|
|
const options: MoveableOptions = {};
|
|
const id = core?.dr?.target?.id;
|
|
|
|
if (!id || !editor.value) return options;
|
|
|
|
const node = editor.value.editorService.getNodeById(id);
|
|
|
|
if (!node) return options;
|
|
|
|
const isPage = node.type === 'page';
|
|
|
|
options.draggable = !isPage;
|
|
options.resizable = !isPage;
|
|
|
|
return options;
|
|
},
|
|
};
|
|
},
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
#app {
|
|
width: 100%;
|
|
height: 100%;
|
|
display: flex;
|
|
}
|
|
|
|
.editor-app {
|
|
width: 100%;
|
|
height: 100%;
|
|
|
|
.m-editor {
|
|
flex: 1;
|
|
height: 100%;
|
|
}
|
|
|
|
.el-overlay-dialog {
|
|
display: flex;
|
|
}
|
|
|
|
.pre-viewer {
|
|
margin: auto;
|
|
|
|
.el-dialog__body {
|
|
padding: 0;
|
|
}
|
|
}
|
|
}
|
|
</style>
|