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

相关推荐
初遇你时动了情16 分钟前
react 项目打包二级目 使用BrowserRouter 解决页面刷新404 找不到路由
前端·javascript·react.js
乔峰不是张无忌33035 分钟前
【HTML】动态闪烁圣诞树+雪花+音效
前端·javascript·html·圣诞树
鸿蒙自习室43 分钟前
鸿蒙UI开发——组件滤镜效果
开发语言·前端·javascript
前端没钱1 小时前
从 Vue 迈向 React:平滑过渡与关键注意点全解析
前端·vue.js·react.js
汪洪墩1 小时前
【Mars3d】设置backgroundImage、map.scene.skyBox、backgroundImage来回切换
开发语言·javascript·python·ecmascript·webgl·cesium
我曾经是个程序员2 小时前
鸿蒙学习记录
开发语言·前端·javascript
顽疲2 小时前
springboot vue 会员收银系统 含源码 开发流程
vue.js·spring boot·后端
羊小猪~~2 小时前
前端入门之VUE--ajax、vuex、router,最后的前端总结
前端·javascript·css·vue.js·vscode·ajax·html5
摸鱼了2 小时前
🚀 从零开始搭建 Vue 3+Vite+TypeScript+Pinia+Vue Router+SCSS+StyleLint+CommitLint+...项目
前端·vue.js
2401_857600953 小时前
基于 SSM 框架 Vue 电脑测评系统:赋能电脑品质鉴定
前端·javascript·vue.js