feat: 编辑器预览功能
This commit is contained in:
65
apps/designer/.vtj/files/45tas1fsz.json
Normal file
65
apps/designer/.vtj/files/45tas1fsz.json
Normal file
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "Test",
|
||||
"locked": false,
|
||||
"inject": [],
|
||||
"state": {},
|
||||
"lifeCycles": {},
|
||||
"methods": {},
|
||||
"computed": {},
|
||||
"watch": [],
|
||||
"css": "",
|
||||
"props": [],
|
||||
"emits": [],
|
||||
"slots": [],
|
||||
"dataSources": {},
|
||||
"__VTJ_BLOCK__": true,
|
||||
"__VERSION__": "1740038923917",
|
||||
"id": "45tas1fsz",
|
||||
"nodes": [
|
||||
{
|
||||
"id": "7pf8hv3wi",
|
||||
"name": "ElButtonGroup",
|
||||
"from": "element-plus",
|
||||
"invisible": false,
|
||||
"locked": false,
|
||||
"children": [
|
||||
{
|
||||
"id": "b9167o6ma",
|
||||
"name": "ElButton",
|
||||
"from": "element-plus",
|
||||
"invisible": false,
|
||||
"locked": false,
|
||||
"children": "Button1",
|
||||
"props": {},
|
||||
"directives": [],
|
||||
"events": {}
|
||||
},
|
||||
{
|
||||
"id": "esn3xh9c2",
|
||||
"name": "ElButton",
|
||||
"from": "element-plus",
|
||||
"invisible": false,
|
||||
"locked": false,
|
||||
"children": "Button2",
|
||||
"props": {},
|
||||
"directives": [],
|
||||
"events": {}
|
||||
},
|
||||
{
|
||||
"id": "ic91nac1u",
|
||||
"name": "ElButton",
|
||||
"from": "element-plus",
|
||||
"invisible": false,
|
||||
"locked": false,
|
||||
"children": "Button3",
|
||||
"props": {},
|
||||
"directives": [],
|
||||
"events": {}
|
||||
}
|
||||
],
|
||||
"props": {},
|
||||
"directives": [],
|
||||
"events": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -5,8 +5,166 @@
|
||||
"name": "低代码编辑器",
|
||||
"homepage": "",
|
||||
"description": "低代码编辑器",
|
||||
"dependencies": [],
|
||||
"pages": [],
|
||||
"dependencies": [
|
||||
{
|
||||
"package": "vue",
|
||||
"version": "latest",
|
||||
"library": "Vue",
|
||||
"urls": [
|
||||
"@vtj/materials/deps/vue/vue.global.prod.js"
|
||||
],
|
||||
"assetsLibrary": "VueMaterial",
|
||||
"required": true,
|
||||
"official": true,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"package": "vue-router",
|
||||
"version": "latest",
|
||||
"library": "VueRouter",
|
||||
"urls": [
|
||||
"@vtj/materials/deps/vue-router/vue-router.global.prod.js"
|
||||
],
|
||||
"assetsLibrary": "VueRouterMaterial",
|
||||
"required": true,
|
||||
"official": true,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"package": "@vtj/utils",
|
||||
"version": "latest",
|
||||
"library": "VtjUtils",
|
||||
"urls": [
|
||||
"@vtj/materials/deps/@vtj/utils/index.umd.js"
|
||||
],
|
||||
"required": true,
|
||||
"official": true,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"package": "@vtj/icons",
|
||||
"version": "latest",
|
||||
"library": "VtjIcons",
|
||||
"urls": [
|
||||
"@vtj/materials/deps/@vtj/icons/style.css",
|
||||
"@vtj/materials/deps/@vtj/icons/index.umd.js"
|
||||
],
|
||||
"required": true,
|
||||
"official": true,
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"package": "@vueuse/core",
|
||||
"version": "latest",
|
||||
"library": "VueUse",
|
||||
"urls": [
|
||||
"@vtj/materials/deps/@vueuse/shared/index.iife.min.js",
|
||||
"@vtj/materials/deps/@vueuse/core/index.iife.min.js"
|
||||
],
|
||||
"required": false,
|
||||
"official": true,
|
||||
"enabled": true,
|
||||
"platform": [
|
||||
"web",
|
||||
"h5"
|
||||
]
|
||||
},
|
||||
{
|
||||
"package": "element-plus",
|
||||
"version": "latest",
|
||||
"library": "ElementPlus",
|
||||
"localeLibrary": "ElementPlusLocaleZhCn",
|
||||
"urls": [
|
||||
"@vtj/materials/deps/element-plus/dark/css-vars.css",
|
||||
"@vtj/materials/deps/element-plus/index.css",
|
||||
"@vtj/materials/deps/element-plus/zh-cn.js",
|
||||
"@vtj/materials/deps/element-plus/index.full.min.js"
|
||||
],
|
||||
"assetsUrl": "@vtj/materials/assets/element/index.umd.js",
|
||||
"assetsLibrary": "ElementPlusMaterial",
|
||||
"required": false,
|
||||
"official": true,
|
||||
"enabled": true,
|
||||
"platform": "web"
|
||||
},
|
||||
{
|
||||
"package": "@vtj/ui",
|
||||
"version": "latest",
|
||||
"library": "VtjUI",
|
||||
"urls": [
|
||||
"@vtj/materials/deps/vxe-table/style.min.css",
|
||||
"@vtj/materials/deps/@vtj/ui/style.css",
|
||||
"@vtj/materials/deps/xe-utils/xe-utils.umd.min.js",
|
||||
"@vtj/materials/deps/vxe-table/index.umd.min.js",
|
||||
"@vtj/materials/deps/@vtj/ui/index.umd.js"
|
||||
],
|
||||
"assetsUrl": "@vtj/materials/assets/ui/index.umd.js",
|
||||
"assetsLibrary": "VtjUIMaterial",
|
||||
"required": false,
|
||||
"official": true,
|
||||
"enabled": true,
|
||||
"platform": "web"
|
||||
},
|
||||
{
|
||||
"package": "ant-design-vue",
|
||||
"version": "latest",
|
||||
"library": "antd",
|
||||
"urls": [
|
||||
"@vtj/materials/deps/ant-design-vue/reset.css",
|
||||
"@vtj/materials/deps/ant-design-vue/dayjs/dayjs.min.js",
|
||||
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/customParseFormat.js",
|
||||
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/weekday.js",
|
||||
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/localeData.js",
|
||||
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/weekOfYear.js",
|
||||
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/weekYear.js",
|
||||
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/advancedFormat.js",
|
||||
"@vtj/materials/deps/ant-design-vue/dayjs/plugin/quarterOfYear.js",
|
||||
"@vtj/materials/deps/ant-design-vue/antd.min.js"
|
||||
],
|
||||
"assetsUrl": "@vtj/materials/assets/antdv/index.umd.js",
|
||||
"assetsLibrary": "AntdvMaterial",
|
||||
"required": false,
|
||||
"official": true,
|
||||
"enabled": false,
|
||||
"platform": [
|
||||
"web"
|
||||
]
|
||||
},
|
||||
{
|
||||
"package": "@vtj/charts",
|
||||
"version": "latest",
|
||||
"library": "VtjCharts",
|
||||
"urls": [
|
||||
"@vtj/materials/deps/echarts/echarts.min.js",
|
||||
"@vtj/materials/deps/@vtj/charts/index.umd.js"
|
||||
],
|
||||
"assetsUrl": "@vtj/materials/assets/charts/index.umd.js",
|
||||
"assetsLibrary": "VtjChartsMaterial",
|
||||
"required": false,
|
||||
"official": true,
|
||||
"enabled": true,
|
||||
"platform": [
|
||||
"web",
|
||||
"h5"
|
||||
]
|
||||
}
|
||||
],
|
||||
"pages": [
|
||||
{
|
||||
"dir": false,
|
||||
"name": "Test",
|
||||
"title": "123",
|
||||
"icon": "",
|
||||
"mask": true,
|
||||
"hidden": false,
|
||||
"raw": false,
|
||||
"pure": false,
|
||||
"meta": "",
|
||||
"cache": false,
|
||||
"id": "45tas1fsz",
|
||||
"type": "page"
|
||||
}
|
||||
],
|
||||
"blocks": [],
|
||||
"apis": [],
|
||||
"meta": [],
|
||||
|
||||
23
apps/designer/.vtj/vue/45tas1fsz.vue
Normal file
23
apps/designer/.vtj/vue/45tas1fsz.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<ElButtonGroup>
|
||||
<ElButton> Button1</ElButton>
|
||||
<ElButton> Button2</ElButton>
|
||||
<ElButton> Button3</ElButton></ElButtonGroup
|
||||
>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
// @ts-nocheck
|
||||
import { defineComponent, reactive } from 'vue';
|
||||
import { ElButtonGroup, ElButton } from 'element-plus';
|
||||
import { useProvider } from '@vtj/renderer';
|
||||
export default defineComponent({
|
||||
name: 'Test',
|
||||
components: { ElButtonGroup, ElButton },
|
||||
setup(props) {
|
||||
const provider = useProvider({ id: '45tas1fsz', version: '1740038923917' });
|
||||
const state = reactive<Record<string, any>>({});
|
||||
return { state, props, provider };
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -27,7 +27,8 @@
|
||||
"@vtj/pro": "^0.9.30",
|
||||
"@vtj/renderer": "^0.9.30",
|
||||
"@vtj/local": "^0.9.30",
|
||||
"@vtj/utils": "0.9.30"
|
||||
"@vtj/utils": "0.9.30",
|
||||
"@vtj/icons": "0.9.30"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vtj/cli": "^0.9.8",
|
||||
|
||||
@@ -1,38 +1,12 @@
|
||||
<template>
|
||||
<div class="designer-container" ref="container"></div>
|
||||
<el-config-provider :locale="zhCn">
|
||||
<Suspense>
|
||||
<router-view></router-view>
|
||||
</Suspense>
|
||||
</el-config-provider>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { Engine, widgetManager, type ProjectModel } from '@vtj/pro';
|
||||
import { ElButton } from 'element-plus';
|
||||
|
||||
import { StorageService } from '@/server';
|
||||
|
||||
const container = ref();
|
||||
const service = new StorageService();
|
||||
const engine = new Engine({
|
||||
container,
|
||||
service,
|
||||
project: {
|
||||
id: 'test',
|
||||
name: '测试'
|
||||
}
|
||||
});
|
||||
|
||||
widgetManager.set('Previewer', {
|
||||
props: {
|
||||
path: (block: any) => {
|
||||
const pathname = location.pathname;
|
||||
return `${pathname}#/preview/${block.id}`;
|
||||
}
|
||||
}
|
||||
});
|
||||
import { ElConfigProvider } from 'element-plus';
|
||||
import zhCn from 'element-plus/es/locale/lang/zh-cn';
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.designer-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
1
apps/designer/src/contants.ts
Normal file
1
apps/designer/src/contants.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const ACCESS_STORAGE_KEY = 'RRO_IDE_ACCESS_STORAGE__';
|
||||
@@ -1,8 +1,10 @@
|
||||
import { createApp } from 'vue';
|
||||
import router from './router';
|
||||
import App from './App.vue';
|
||||
import ElementPlus from 'element-plus';
|
||||
import './style/index.scss';
|
||||
|
||||
const app = createApp(App);
|
||||
app.use(router);
|
||||
app.use(ElementPlus);
|
||||
app.mount('#app');
|
||||
|
||||
21
apps/designer/src/router.ts
Normal file
21
apps/designer/src/router.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { createRouter, createWebHashHistory } from 'vue-router';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: () => import('./views/index.vue')
|
||||
},
|
||||
{
|
||||
path: '/preview/:id',
|
||||
name: 'preview',
|
||||
component: () => import('./views/preview.vue')
|
||||
}
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes
|
||||
});
|
||||
|
||||
export default router;
|
||||
@@ -9,3 +9,7 @@ body,
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#vtjLink {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<template>
|
||||
<div ref="container"></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { Engine } from '@vtj/pro';
|
||||
import { StorageService } from '@/server';
|
||||
|
||||
const container = ref();
|
||||
const service = new StorageService();
|
||||
const engine = new Engine({
|
||||
container,
|
||||
service,
|
||||
project: {
|
||||
id: 'test',
|
||||
name: '测试'
|
||||
}
|
||||
});
|
||||
|
||||
engine.ready(() => {
|
||||
console.log('ready');
|
||||
});
|
||||
</script>
|
||||
46
apps/designer/src/views/index.vue
Normal file
46
apps/designer/src/views/index.vue
Normal file
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div class="designer-container" ref="container"></div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import {
|
||||
Engine,
|
||||
widgetManager,
|
||||
LocalService,
|
||||
MemoryService
|
||||
// type ProjectModel
|
||||
} from '@vtj/pro';
|
||||
|
||||
import { StorageService } from '@/service';
|
||||
|
||||
const container = ref();
|
||||
const service = new StorageService();
|
||||
// const service = new StorageService();
|
||||
|
||||
const engine = new Engine({
|
||||
container,
|
||||
service,
|
||||
project: {
|
||||
id: 'test',
|
||||
name: '测试'
|
||||
}
|
||||
});
|
||||
|
||||
widgetManager.set('Previewer', {
|
||||
props: {
|
||||
path: (block: any) => {
|
||||
console.log('block', block);
|
||||
const pathname = location.pathname;
|
||||
return `${pathname}#/preview/${block.id}`;
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.designer-container {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
36
apps/designer/src/views/preview.vue
Normal file
36
apps/designer/src/views/preview.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import { createRenderer } from '@vtj/renderer';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { StorageService } from '@/service';
|
||||
import { getCurrentInstance } from 'vue';
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const service = new StorageService();
|
||||
|
||||
const instance = getCurrentInstance();
|
||||
|
||||
const app = instance?.appContext.app;
|
||||
|
||||
const file = await service.getFile(route.params.id.toString());
|
||||
|
||||
console.log('file', file);
|
||||
|
||||
Object.assign(route.meta, file.meta);
|
||||
const el = app?._container;
|
||||
if (file?.type === 'page') {
|
||||
el.classList.add('is-page');
|
||||
}
|
||||
const isPure = file?.pure;
|
||||
if (isPure) {
|
||||
el.classList.add('is-pure');
|
||||
}
|
||||
|
||||
const { renderer } = createRenderer({
|
||||
dsl: file
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component :is="renderer" />
|
||||
</template>
|
||||
@@ -19,7 +19,7 @@ const routes: Array<RouteRecordRaw> = [
|
||||
title: '低代码编辑器',
|
||||
icon: 'ant-design:edit-outlined',
|
||||
app: {
|
||||
url: 'https://localhost:10011/__vtj__/',
|
||||
url: 'https://localhost:10011',
|
||||
name: 'low-code-designer',
|
||||
sync: true,
|
||||
alive: true,
|
||||
|
||||
Reference in New Issue
Block a user