Vue进阶之Vue无代码可视化项目(六)

渲染引擎(渲染器)

接下来要做的是,中间区域Block相关的内容,block相关的内容最重要的就是,数据协议设计和整体渲染器的逻辑

  1. 渲染器概念:简单点说就是,封装他的组件。比如做了一个图表,可以说封装了一个图表组件,如果做了一个表单校验,可以说做了一个表单校验组件,或者写了一些业务组件,但是这些点要是上升一点,就是,表单渲染 – 表单渲染器,表单渲染组件,表单规则约定 – 表单规则校验器;可以美化这些词语,提高简历

  2. 数据协议:左边物料区有很多的物料列表,将左边的物料拖到中间编排区进行编排,拖拽之后,这些内容区域就能组装成一个页面,那么从左边拖的时候,这些物料需要定义一个数据结构,这个数据结构就叫做数据协议,我们从左边拖过来的时候,需要将对应的数据加到右边页面中去,加进去的时候,我们的页面相当于又是一个大JSON,这是属于页面的协议,左边物料是物料协议。

  3. 物料渲染:我们有很多很多的物料,这些物料都要取通过条件规则判断来渲染,如果来的物料是文本,那么就按照文本的方式去渲染,如果来的物料是视频,那么就按照视频播放器的逻辑去渲染,如果来的物料是图表,就按照图表的渲染器去渲染,以此类推。

初版

创建物料blocks文件夹

  • src
    • blocks
      • external
      • internal
        • TextBlock.vue
        • ImageBlock.vue
        • ChartBlock.vue

blocks:可以分内部block(基础block)和外部block,就是最后代码结构内容和block整体渲染逻辑中,是可以加载外部block内容的,比如将有些block单独封装好之后,上传到远程,这时候远程能拉取到对应的js代码,通过umd打包后放上去,然后在使用的地方加载过来,植入到我们代码中。

TextBlock.vue

<!-- 共同去处理、规范约定他们 -->
 <!-- Text/Image/Chart -->

<template>
  <div>{
  {text.content}}</div>
</template>

<script setup lang='ts'>
const text={
     
  type:"text",
  content:"这是一段文本"
}
</script>

<style scoped>

</style>

ChartBlock.vue

<!-- 共同去处理、规范约定他们 -->
 <!-- Text/Image/Chart -->

 <template>
    <div>{
  {chart.type}}</div>
  </template>
  
  <script setup lang='ts'>
  const chart={
     
    type:"chart",
    content:"这是一段文本",
    props:{
     
        xAxis:['Mon','Tue','Wed','Thu','Fri','Sat','Sun'],
        yAxis:[820,930,901,934,1290,1330,1320]
    }
  }
  </script>
  
  <style scoped>
  
  </style>

ImageBlock.vue

<!-- 共同去处理、规范约定他们 -->
 <!-- Text/Image/Chart -->

 <template>
    <div>
        <img :src="image.props.src" :alt="image.props.alt" />
    </div>
  </template>
  
  <script setup lang='ts'>
  const image={
     
    type:"image",
    content:"image",
    props:{
     
        src:"https://cdnjs.cloudflare.com/ajax/libs/twemoji/11.3.0/2/svg/1f469-200d-1f692.svg",
        alt:"这是一个图片",
    }
  }
  </script>
  
  <style scoped>
  
  </style>

LayoutView.vue

<SmoothDndDraggable>
  <TextBlock/>
</SmoothDndDraggable>
<SmoothDndDraggable>
  <ImageBlock/>
</SmoothDndDraggable>
<SmoothDndDraggable>
  <ChartBlock/>
</SmoothDndDraggable>
import TextBlock from '@/blocks/internal/TextBlock.vue'
import ImageBlock from '@/blocks/internal/ImageBlock.vue'
import ChartBlock from '@/blocks/internal/ChartBlock.vue'

全部代码:

<template>
  <div class="layout-wrapper" :class="{debug}" @click="debugStore.toggleDebug">
      <LeftPanel />
      <div>
        <SmoothDndContainer class="block-group" 
          orientation="vertical"
          tag="div"  group-name="blocks" 
          @drop="(payload)=>{
            console.log('payload',payload);
            const newBlocks=applyDrag(blocks,payload)
            editorStore.updateBlocks(newBlocks)
          }"  
          >
            <!-- <SmoothDndDraggable v-for="block in blocks" :key="block">
              <div class="block-item">{
   {block}}</div>
            </SmoothDndDraggable> -->
            <SmoothDndDraggable>
              <TextBlock/>
            </SmoothDndDraggable>
            <SmoothDndDraggable>
              <ImageBlock/>
            </SmoothDndDraggable>
            <SmoothDndDraggable>
              <ChartBlock/>
            </SmoothDndDraggable>
          
          </SmoothDndContainer>
      </div>
      <div></div>
</div>
</template>

<script lang="ts" setup>
// import AppLeftPanel from '@/components/AppLeftPanel/AppLeftPanel';
import LeftPanel from '@/components/LeftPanel.vue';
import {
     useDebugStore} from '@/stores/debug'
import {
     useEditorStore} from '@/stores/editor'
import {
     SmoothDndContainer} from '@/components/SmoothDnd/SmoothDndContainer'
import {
     SmoothDndDraggable} from '@/components/SmoothDnd/SmoothDndDraggable'
import TextBlock from '@/blocks/internal/TextBlock.vue'
import ImageBlock from '@/blocks/internal/ImageBlock.vue'
import ChartBlock from '@/blocks/internal/ChartBlock.vue'
import {
      storeToRefs } from 'pinia';
import type {
      DropResult } from 'smooth-dnd';
import {
     arrayMove} from '@/utils/array';


const debugStore = useDebugStore()
const editorStore = useEditorStore()

const {
     debug}=storeToRefs(debugStore)
const {
     blocks}=storeToRefs(editorStore)

const applyDrag=<T extends any[]>(arr:T,dragResult:DropResult)=>{
     
  const {
     addedIndex,removedIndex,payload}=dragResult

  const result = [...arr]

  if(addedIndex===null) return result;

  // 添加:从外面拖进来是添加
  if(addedIndex!==null&&removedIndex===null){
     
    result.splice(addedIndex,0,payload)
  }

  // 移动:内部拖拽是移动
  if(addedIndex!==null&&removedIndex!==null){
     
    return arrayMove(result,removedIndex,addedIndex)
  }
  return result
}

</script>
<style>
  • 23
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值