vue + Lodop 制作可视化设计页面 实现打印设计功能(二)

历史:

vue2 + Lodop 制作可视化设计页面 实现打印设计功能(一)

前言:

之前本来打算用直接拿之前做的vue2版本改改就发的,但考虑到现在主流都是vue3了,所以从这篇文章开始使用vue3来写,以及最后的demo也使用vue3

考虑到之前发的一些点过于分散,这篇开始打算就从头开始写这个功能,每篇最后发个本篇的示例demo

主要技术栈:vue3+vite+pinia+less+typescript

目录:

  1. 项目创建及模块定义,简单实现拖拽新增
  2. 新增第一个自定义组件-HPText(文本组件)
  3. 引入lodop,打印预览
  4. 组件点击拖拽移动
  5. 新增HPText组件的菜单,组件菜单设置时组件动态变化
  6. 框选组件,批量移动
  7. 待定...

正文:

创建vue3+vite项目

这个不用多说了,不属于本系列的范围

项目目录

最后项目创建后的目录大概长这样

定义设计页面viewport

<script setup lang="ts">
import {ref,h,resolveComponent} from 'vue'
import {QYComponent} from "../../../domains/qy-component.ts";

const edit = ref(null)
const page = ref({
  height: 560,
  width: 944,
})

const widgetStore = ref<QYComponent[]>([])

const 测试数据 = [{
  uuid:'123',
  attr: {
    x: 10,
    y: 10,
    width: 90,
    height: 20,
  },
}]

const dropToAddCom = (ev) => {
  ev.preventDefault()
  const rest = edit.value.getBoundingClientRect();
  测试数据[0].attr.x = Math.round(ev.clientX - rest.x)
  测试数据[0].attr.y = Math.round(ev.clientY - rest.y)
  widgetStore.value = [...测试数据];
}

const dragOver = (ev) => {
  ev.preventDefault()
}

const handleMouseDown = (ev) => {

}

</script>

<template>
  <div class="holder" id="viewport" ref="viewport" data-type="viewport">
    <div
        :style="{
          height: page.height + 'px',
          width: page.width + 'px'
          }"
        ref="edit"
        class="screen"
        @dragover.prevent="dragOver"
        @drop="dropToAddCom($event)"
    >

      <!-- 组件 -->
      <div
          v-for="(moduleData,index) in widgetStore"
          :style="{
          position: 'absolute',
          top: `${moduleData.attr.y}px`,
          left: `${moduleData.attr.x}px`,
          width: `${moduleData.attr.width}px`,
          height:`${moduleData.attr.height}px`
        }"
      >
        <component
            :is="input"
            :com="moduleData"
        ></component>
      </div>

    </div>
  </div>
</template>

<style scoped>
.holder {
  position: relative;
  width: 100%;
  display: flex;
  justify-content: left;
  overflow: auto;
  font-size: 0;
  border: 1px solid #f5f5f5;
  border-width: 0 1px;
  background-image: linear-gradient(45deg, #f5f5f5 25%, transparent 0, transparent 75%, #f5f5f5 0),
  linear-gradient(45deg, #f5f5f5 25%, transparent 0, transparent 75%, #f5f5f5 0);
  background-position: 0 0, 13px 13px;
  background-size: 26px 26px;
}

.screen {
  margin: 20px;
  transform-origin: center top;
  position: relative;
  box-shadow: 0 0 5px 1px #cccccc;
  background-color: #ffffff;
  background-repeat: no-repeat;
}

.wrapper {
  margin: 20px;
  position: relative;
}
</style>

定义组件列表components-panel

<script setup lang="ts">
import {ref} from 'vue'


const dragStart = (ev) => {
  
}
</script>

<template>
  <div class="component-main" style="display: flex;flex-direction: column">
    <div style="margin: 5px;background: lightskyblue;color: white"
         :draggable="true"
         @dragstart="dragStart($event)">
      文本
    </div>
  </div>
</template>

<style scoped>
.component-main {
  border-radius: 5px;
  height: 100%;
  width: 200px;
  overflow-x: hidden;
  overflow-y: auto;
}
</style>

修改App.vue

<script setup lang="ts">
import viewport from './components/print-designer/viewport/index.vue'
import componentsPanel from './components/print-designer/components-panel/index.vue'


</script>

<template>
  <div class="main" data-theme="qy-designer">
    <components-panel/>
    <viewport/>
  </div>
</template>

<style scoped>
.main {
  display: flex;
  flex-direction: row;
  width: 100%;
  height: 100%;
  user-select: none;
}
</style>

效果

注:这里使用的技术点因为已经在第一篇讲了,所以这里就不再赘述了

demo示例

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值