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

历史:

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

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

前言:

在之前的几篇文章里已经完成了项目的创建,并且实现了简单的拖拽新增,这篇主要是实现第一个组件(HPText)

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

目录:

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

正文:

定义基类class

首先抽象组件,对于一个打印组件来说,最重要的属性如下:

|--------|------|
| 属性名 | 意义 |
| id | 唯一标识 |
| title | 内容标题 |
| type | 组件类型 |
| x | 横坐标 |
| y | 纵坐标 |
| height | 高 |
| width | 宽 |

那我们就依据这个来定义一个抽象类当做所有组件的基类

TypeScript 复制代码
import {nanoid} from "nanoid";

/**
 * 位置信息
 */
export interface ComponentAttr {
    x: number
    y: number
    width: number
    height: number
}

export abstract class QYComponent {
    id: string
    title:string
    readonly type: string
    attr:ComponentAttr={
        x: 10,
        y: 10,
        width: 90,
        height: 20,
    }

    constructor(type: string, attr: Partial<ComponentAttr>) {
        this.id = nanoid()
        this.type = type

        this.attr = { ...this.attr, ...attr }
    }
}

定义HPText 的 class

直接继承与前面定义的基类即可,并定义一些初始值

TypeScript 复制代码
export class HPText extends QYComponent {
    //可以加一些Text特有的属性

    constructor() {
        super('HPText', { width: 50, height: 50 })
    }
}

定义一个HPText 的 vue文件 用于显示

在props 定义一个com用于接收数据

TypeScript 复制代码
<script lang="ts">
import {defineComponent, PropType, ref, toRef} from "vue";
import {HPText} from "./index.ts";

export default defineComponent({
  name: 'HPText',
  props: {
    com: {
      type: Object as PropType<HPText>,
      required: true,
    },
  },
  setup(props) {
    const title = toRef(props.com, 'title')


    return{
      title,
    }
  },
  mounted() {

  }
})
</script>

<template>
  <div style="font-size: 12px;">
    {{title}}
  </div>
</template>

<style scoped>

</style>

准备注册组件

首先是定义一个共用的ts文件,让打印的组件都在这里声明,最后把此ts文件在mian.ts中注册即可

index.ts

TypeScript 复制代码
import HPText from './text/index.vue'
import type {App} from 'vue'

const components = [
    HPText,
]


const install = function (app: App):void {
    //组件注册
    components.forEach(component => {
        app.component(component.name,component)
    })
}

export default {
    install,
}

mian.ts

TypeScript 复制代码
import widgets from './components/print-designer/widgets/index.ts'


app.use(widgets)

这样我们的HPText 的文件也就创建以及注册好了,现在我们需要改动前面的代码使其能够使用HPText

代码改动

1.首先是dragStart

这里我定义了一个组件列表数组

TypeScript 复制代码
export const datas = [
    {
        "id": "1",
        "title": "文本",
        "type": "HPText"
    }
]
TypeScript 复制代码
const dragStart = (ev,index) => {
  ev.dataTransfer.setData('index', index)
}
2.其次是dropToAddCom
TypeScript 复制代码
const  dropToAddCom = async (ev:DragEvent) => {
  ev.preventDefault()
  let index = ev.dataTransfer.getData('index')
  //初始化组件
  let com = await createComponent(datas[index].type)
  //获取父容器的边界矩形
  const rest = edit.value.getBoundingClientRect();
  //插入x,y坐标
  com.attr.x = Math.round(ev.clientX-rest.x)
  com.attr.y = Math.round(ev.clientY-rest.y)
  //拼接参数
  widgetStore.value.push({
    ...com,
    ...datas[index]
  });
}

其中createComponent()是一个工具方法,主要是查询指定目录下的文件并初始化创建组件

TypeScript 复制代码
import { camelCase } from 'lodash-es'

export async function createComponent(name: string) {
    const modules: Record<string, () => Promise<any>> = import.meta.glob([
        './print-designer/widgets/**/*.ts'
    ])
    const file = camelCase(name.substring(2))
    const paths = Object.keys(modules)
    let path = paths.find(m => m.includes(`${file}/index.ts`))
    if (path) {
        const mod = await modules[path]()
        return new mod.default()
    }

    throw Error(`没有找到组件,类型: ${name}.`)
}

至此,HPText 完成

新增依赖

"lodash-es": "^4.17.21"

"nanoid": "^5.0.7"

效果

demo示例

相关推荐
徐同保15 分钟前
上传文件,在前端用 pdf.js 提取 上传的pdf文件中的图片
前端·javascript·pdf
怕浪猫16 分钟前
React从入门到出门第四章 组件通讯与全局状态管理
前端·javascript·react.js
博主花神17 分钟前
【React】扩展知识点
javascript·react.js·ecmascript
内存不泄露22 分钟前
基于Spring Boot和Vue 3的智能心理健康咨询平台设计与实现
vue.js·spring boot·后端
欧阳天风24 分钟前
用setTimeout代替setInterval
开发语言·前端·javascript
EndingCoder28 分钟前
箭头函数和 this 绑定
linux·前端·javascript·typescript
xkxnq34 分钟前
第一阶段:Vue 基础入门(第 11 天)
前端·javascript·vue.js
小oo呆39 分钟前
【自然语言处理与大模型】LangGraphV1.0入门指南:核心组件Nodes
前端·javascript·easyui
行走的陀螺仪1 小时前
在UniApp H5中,实现路由栈的持久化
前端·javascript·uni-app·路由持久化·路由缓存策略
内存不泄露1 小时前
基于Spring Boot和Vue的在线考试系统设计与实现
vue.js·spring boot·后端