在业务系统开发中,打印功能往往需要持续维护和调整,传统固定排版方式难以满足灵活需求。本文将介绍基于Vue3开发的可扩展打印模板设计器解决方案。
传统标签打印功能存在明显局限性,它通常被设计为一次性输出功能,而非可维护的编辑系统。以鞋盒标为例,需要展示款号、颜色、尺码等多样化信息,且不同客户的布局需求各异,甚至同一客户也会频繁调整模板样式。若每次调整都需要开发人员修改代码并重新发版,不仅效率低下,也难以满足业务快速变化的需求。
针对这一痛点,我开发了Vue3打印模板画布print-canvas-designer,配套提供了真实接入示例项目print-canvas-examples及相关文档。

print-canvas-designer 主要面向需要灵活排版的打印场景,如商品标签、物流面单等。
当前功能包括:
该设计器的核心价值在于画布本身的编辑能力,而非固定的UI布局。不同业务可根据需求自由定义所需组件和属性。
为展示实际项目中的接入方案,print-canvas-examples提供了三类典型场景:
在线示例(点我)

安装依赖:
npm install print-canvas-designer
引入样式文件:
import 'print-canvas-designer/style.css'
在页面中使用编辑器:
模板数据通过v-model双向绑定,业务系统可将JSON保存至数据库,实现模板持久化。
完整编辑器适合快速启动项目,但实际业务系统通常需要:
此时可选择仅接入PrintCanvas,自主构建界面布局。
添加文本
添加条形码
面板与画布通过designer实例通信,业务代码可调用:
designer.updateElement(activeId, { field: 'styleColorSize' })
designer.updateElementStyle(activeId, { width: 200, height: 42 })
designer.removeElement(activeId)
designer.undo()
designer.redo()
designer.save()
这种设计实现了编辑交互与业务逻辑的分离。
对于固定结构的业务区块,可封装为独立组件。例如鞋盒标信息区域通常包含:
业务可定义专用组件,由画布处理基础交互,业务代码负责具体内容和属性编辑。
import {
defaultPrintComponents,
type PrintComponentDefinition
} from 'print-canvas-designer'
import ShoeInfoBlockRender from './ShoeInfoBlockRender.vue'
import ShoeInfoBlockInspector from './ShoeInfoBlockInspector.vue'const shoeInfoBlock: PrintComponentDefinition = {
type: 'shoe-info-block',
label: '鞋盒标信息块',
icon: 'i-lucide-tag',
render: ShoeInfoBlockRender,
inspector: ShoeInfoBlockInspector,
createElement: (point) => ({
id: `shoe_${Date.now()}`,
type: 'shoe-info-block',
name: '鞋盒标信息块',
props: {
title: 'SPORT SERIES',
mainText: 'RUNNER-01 / BLACK / 42',
subText: 'STYLE / COLOR / SIZE',
accentColor: '#2563eb'
},
style: {
position: 'absolute',
left: point.x,
top: point.y,
width: 260,
height: 92,
rotate: 0
}
})
}export const components = [
...defaultPrintComponents,
shoeInfoBlock
]
注册组件后即可在编辑器中使用:
自定义组件机制是画布SDK的核心扩展能力,适用于各种接入模式。

模板保存布局配置,实际数据在打印时动态注入。例如文本元素可关联字段名:
{
"type": "text",
"name": "款色码",
"field": "styleColorSize",
"style": {
"left": 24,
"top": 32,
"width": 220,
"height": 42
}
}
业务数据预处理后传入:
const printData = {
styleColorSize: [product.style, product.color, product.size].join(' / ')
}
这种方式保持了画布的通用性,无需为特定业务定制布局规则。
图片组件支持直接填写地址或业务上传:
const uploadImage = async (file: File) => {
const url = await uploadToObjectStorage(file)
return url
}
输出功能方面,完整编辑器内置打印和PDF导出,仅接入画布时也可通过API实现相同功能。
当前版本已实现画布核心功能与业务扩展机制,能够满足标签类模板的基本需求。
未来计划重点完善:
这款基于Vue3的打印模板设计器通过灵活的架构设计,既提供了开箱即用的完整解决方案,又支持深度定制开发,能够有效解决业务系统中打印模板的维护难题。