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

相关推荐
qq. 28040339844 小时前
js 原型链分析
开发语言·javascript·ecmascript
格鸰爱童话4 小时前
next.js(二)——从react到next.js
前端·javascript·react.js
Hammer Ray8 小时前
SourceMap知识点
javascript·sourcemap
Sheldon一蓑烟雨任平生8 小时前
webpack 从零构建 Vue3
webpack·typescript·vue3·webpack配置·从零构建vue3
CDwenhuohuo11 小时前
微信小程序里用 setData() 修改数据并打印输出 的几种写法
javascript·微信小程序·小程序
前端一小卒12 小时前
生产环境Sourcemap策略:从苹果事故看前端构建安全架构设计
前端·javascript
漠月瑾-西安12 小时前
React 组件二次封装实践:解决自定义 Props 传递导致的 DOM 警告问题
typescript·ant design·react hooks·react组件封装
im_AMBER13 小时前
React 18
前端·javascript·笔记·学习·react.js·前端框架
老前端的功夫13 小时前
Vue2中key的深度解析:Diff算法的性能优化之道
前端·javascript·vue.js·算法·性能优化
集成显卡13 小时前
AI取名大师 | PM2 部署 Bun.js 应用及配置 Let‘s Encrypt 免费 HTTPS 证书
开发语言·javascript·人工智能