Vue无代码可视化项目
- 编排引擎
-
- smooth-dnd
-
- LeftPanel.vue
- LayoutView.vue
- stores/debug.ts
- stores/editor.ts
- AppNavigator.vue
- 添加-左侧栏添加到中间部分
-
- LayoutView.vue
- store/editor.ts
- LeftPanel.vue
- 移动-中间部分区域的位置更改
-
- 新建文件夹utils、文件array.ts
-
- array.ts
- LayoutView.vue
编排引擎
smooth-dnd
LeftPanel.vue
<SmoothDndContainer class="block-group"
behaviour="copy"
tag="div" group-name="blocks"
@drag-start="(e,v)=>console.log(e,v)"
@drag-leave="(e,v)=>console.log(e,v)"
@drop="(e)=>console.log('drop',e)"
:get-child-payload="(index:number)=>index"
>
<SmoothDndDraggable v-for="i in 10" :key="i">
<div class="block-item">{
{i}}</div>
</SmoothDndDraggable>
</SmoothDndContainer>
.block-item{
width: 40px;
height: 40px;
background-color: #fff;
border: 1px solid #e8e8e8;
margin-bottom: 8px;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
transition:background-color 0.3s;
cursor: move;
user-select: none;
}
.block-group{
padding: 8px;
display: flex;
flex-wrap: wrap;
gap: 8px;
}
</style>
全部代码:
<script setup lang="ts">
import {
Lightning, Share } from '@icon-park/vue-next'
import {
ref } from 'vue';
import {
SmoothDndContainer} from '@/components/SmoothDnd/SmoothDndContainer'
import {
SmoothDndDraggable} from '@/components/SmoothDnd/SmoothDndDraggable'
type Mode = 'outline'|'blocks'|null
const mode = ref<Mode>(null)
const toggleMode = (newMode:Mode) => {
if(newMode === mode.value){
mode.value = null
}else{
mode.value = newMode
}
}
</script>
<template>
<div class="left-panel-wrapper">
<div class="left-panel-left">
<div class="btn" :class="{active:mode==='outline'}" @click="()=>toggleMode('outline')">
<Lightning />
</div>
<div class="btn" :class="{active:mode==='blocks'}" @click="()=>toggleMode('blocks')">
<Share />
</div>
</div>
<!-- 接入动画 -->
<transition name="app-left-panel-drawer">
<div class="left-panel-content" v-show="mode">
{
{mode}}
<!-- 面板中使用SmoothDnd -->
<SmoothDndContainer class="block-group"
behaviour="copy"
tag="div" group-name="blocks"
@drag-start="(e,v)=>console.log(e,v)"
@drag-leave="(e,v)=>console.log(e,v)"
@drop="(e)=>console.log('drop',e)"
:get-child-payload="(index:number)=>index"
>
<SmoothDndDraggable v-for="i in 10" :key="i">
<div class="block-item">{
{i}}</div>
</SmoothDndDraggable>
</SmoothDndContainer>
</div>
</transition>
</div>
</template>
<style scoped>
.left-panel-wrapper {
display: flex;
height: 100%;
background-color: #f5f5f5;
border: 1px solid #e8e8e8;
}
.left-panel-left{
display: flex;
padding:0 10px;
flex-direction: column;
align-items: center;
width: 50px;
height: 100%;
background-color: #e8e8e8;
}
.btn{
width: 32px;
height: 32px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
border-radius: 6px;
margin-top:20px;
/* &:hover{
background-color: #f5f5f5;
} */
}
.btn:hover{
background-color: #f5f5f5;
}
/* 被激活时候的特定样式 */
.btn.active{
background-color: rgb(0,196,83);
color: #fff;
}
.left-panel-content{
flex: 1;
width: 280px;
height: 100%;
background-color: #f5f5f5;
overflow: hidden;
}
/* 下面我们会解释这些 class 是做什么的 */
.app-left-panel-drawer-enter-active,
.app-left-panel-drawer-leave-active {
transition: width 0.1s cubic-bezier(0.3, 0.1, 0.3, 1);
}
.app-left-panel-drawer-enter-from,
.app-left-panel-drawer-leave-to {
width: 0;
}
.app-left-panel-drawer-content {
width: calc(var(--panel-width) - 60px);
height: 100%;
padding: 16px;
}
.block-item{
width: 40px;
height: 40px;
background-color: #fff;
border: 1px solid #e8e8e8;
margin-bottom: 8px;
display: flex;
justify-content: center;
align-items: center;
font-size: 14px;
transition:background-color 0.3s;
cursor: move;
user-select: none;
}
.block-group{
padding: 8px;
display: flex;
flex-wrap: wrap;
gap: 8px;
}
</style>
LayoutView.vue
<SmoothDndContainer class="block-group"
orientation="vertical"
tag="div" group-name="blocks"
@drop="(payload)=>editorStore.addBlock(payload)"
>
<SmoothDndDraggable v-for="block in blocks" :key="block"