229 lines
5.2 KiB
Vue
229 lines
5.2 KiB
Vue
<template>
|
||
<div class="low_box">
|
||
<div class="header">
|
||
<div class="title">可视化系统</div>
|
||
<div class="web">pc</div>
|
||
<div class="btn">
|
||
<a-button type="primary" @click="view">确定</a-button>
|
||
</div>
|
||
</div>
|
||
<div class="content">
|
||
<div class="left">
|
||
<div class="title">组件</div>
|
||
<VueDraggable
|
||
v-model="store.components"
|
||
:animation="150"
|
||
:group="{ name: 'people', pull: 'clone', put: false }"
|
||
:sort="false"
|
||
:clone="clone"
|
||
@start="onStart"
|
||
@end="onEnd"
|
||
>
|
||
<div v-for="item in store.components" :key="item.id" class="tem_btn">
|
||
{{ item.name }}
|
||
</div>
|
||
</VueDraggable>
|
||
</div>
|
||
<div ref="targetContent" class="center">
|
||
<VueDraggable
|
||
v-model="store.previewScheme"
|
||
:group="{name: 'designer', pull: 'clone', put: false}"
|
||
ghost-class="ghost"
|
||
class="canvas"
|
||
>
|
||
<NestedFunction v-model="store.previewScheme"></NestedFunction>
|
||
</VueDraggable>
|
||
</div>
|
||
<!-- <div class="right">-->
|
||
<!-- <component :is="componentsList[store?.nowComponent?.set]"></component>-->
|
||
<!-- </div>-->
|
||
</div>
|
||
</div>
|
||
</template>
|
||
<script setup lang="ts">
|
||
import {VueDraggable} from "vue-draggable-plus";
|
||
import {onMounted, watch} from 'vue';
|
||
import {uuid} from 'lsp-uuid';
|
||
import {componentScheme} from "@/schemes/scheme";
|
||
import {useSchemeStore} from '@/stores/useSchemeStore';
|
||
import {IComponent} from "@/type/IComponent";
|
||
import NestedFunction from "@/components/NestedFunction.vue";
|
||
|
||
|
||
let componentsList = [];
|
||
const store = useSchemeStore();
|
||
|
||
watch(store, (n) => {
|
||
console.log("数据", n);
|
||
});
|
||
|
||
const baseScheme =
|
||
{
|
||
"type": "AdaptivePage",
|
||
"name": "AdaptivePage",
|
||
"id": uuid(),
|
||
"version": "2.0",
|
||
"props": {},
|
||
"class": "",
|
||
"style": "",
|
||
"variables": {},
|
||
"dataSources": {},
|
||
"functions": {},
|
||
"orchestrations": {},
|
||
"events": {},
|
||
"slots": {},
|
||
"header": {},
|
||
"footer": {},
|
||
"children": [],
|
||
"meta": {}
|
||
}
|
||
store.$onAction(
|
||
({
|
||
name, // action 名称
|
||
after, // 在 action 返回或解决后的钩子
|
||
onError, // action 抛出或拒绝的钩子
|
||
}) => {
|
||
after((result) => {
|
||
console.log(result);
|
||
})
|
||
// 如果 action 抛出或返回一个拒绝的 promise,这将触发
|
||
onError((error) => {
|
||
console.warn(
|
||
`Failed "${name}" after\nError: ${error}.`
|
||
)
|
||
})
|
||
}
|
||
)
|
||
//初始化scheme
|
||
const initScheme = () => {
|
||
store.initPreviewScheme([baseScheme])
|
||
componentsList = Object.values(componentScheme);
|
||
store.initComponents(componentsList);
|
||
}
|
||
|
||
|
||
onMounted(() => {
|
||
initScheme();
|
||
// @ts-ignore
|
||
});
|
||
|
||
const clone = function (element: IComponent) {
|
||
return {
|
||
id: `${element.type}-${uuid()}`,
|
||
name: element.name,
|
||
type: element.type,
|
||
props: element.props,
|
||
class: element.class,
|
||
designer: '',
|
||
text: element.text,
|
||
children: [],
|
||
style: element.style,
|
||
visible: "",
|
||
slots: element.slots,
|
||
disable: "",
|
||
events: {},
|
||
loop: {},
|
||
};
|
||
}
|
||
|
||
const onEnd = (obj: any) => {
|
||
console.log(obj)
|
||
// const {oldDraggableIndex} = obj;
|
||
// store.previewData(store.component[oldDraggableIndex]);
|
||
// store.nowComponentsData(store.component[oldDraggableIndex]);
|
||
};
|
||
|
||
const onStart = function () {
|
||
console.log("start")
|
||
}
|
||
|
||
const view = () => {
|
||
localStorage.setItem("lowcode", JSON.stringify(store.previewScheme));
|
||
window.open(location.href.replace("/#/", "/preview/#/"));
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.low_box {
|
||
width: 100%;
|
||
height: 100%;
|
||
overflow: hidden;
|
||
background-color: #f2f2f2;
|
||
|
||
.header {
|
||
height: 65px;
|
||
background-color: #fff;
|
||
display: flex;
|
||
flex-direction: row;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 0 20px;
|
||
}
|
||
|
||
.content {
|
||
display: flex;
|
||
flex-direction: row;
|
||
height: calc(100vh - 66px);
|
||
|
||
.left {
|
||
width: 300px;
|
||
height: 100%;
|
||
overflow: hidden;
|
||
background-color: #fff;
|
||
border-top: 1px solid #dddddd;
|
||
overflow-y: auto;
|
||
|
||
.title {
|
||
font-size: 16px;
|
||
color: #333;
|
||
line-height: 50px;
|
||
width: calc(100% - 40px);
|
||
margin-left: 20px;
|
||
border-bottom: 1px solid #f2f2f2;
|
||
clear: both;
|
||
}
|
||
|
||
.tem_btn {
|
||
padding: 0 10px;
|
||
height: 30px;
|
||
line-height: 30px;
|
||
text-align: center;
|
||
font-size: 14px;
|
||
color: #666;
|
||
background-color: #f2f2f2;
|
||
border-radius: 4px;
|
||
cursor: move;
|
||
user-select: none;
|
||
margin-top: 20px;
|
||
float: left;
|
||
margin-left: 20px;
|
||
}
|
||
}
|
||
|
||
.center {
|
||
flex: 1;
|
||
padding: 20px;
|
||
background-color: #f2f2f2;
|
||
|
||
.canvas {
|
||
background-color: #fff;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.ghost {
|
||
background-color: #f00 !important;
|
||
}
|
||
}
|
||
|
||
.right {
|
||
width: 300px;
|
||
height: 100%;
|
||
overflow: hidden;
|
||
background-color: #fff;
|
||
border-top: 1px solid #dddddd;
|
||
}
|
||
}
|
||
}
|
||
</style>
|