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示例

相关推荐
无心使然云中漫步36 分钟前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者42 分钟前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
xnian_1 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js
罗政2 小时前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
麒麟而非淇淋2 小时前
AJAX 入门 day1
前端·javascript·ajax
2401_858120532 小时前
深入理解MATLAB中的事件处理机制
前端·javascript·matlab
阿树梢2 小时前
【Vue】VueRouter路由
前端·javascript·vue.js
随笔写4 小时前
vue使用关于speak-tss插件的详细介绍
前端·javascript·vue.js
快乐牌刀片884 小时前
web - JavaScript
开发语言·前端·javascript
秋雨凉人心4 小时前
call,apply,bind在实际工作中可以使用的场景
javascript