template-designer
v0.11.8
Published
模板拖拽设计器组件库
Maintainers
Readme
模板设计器组件库
一个基于Vue 3的可视化模板设计器组件库,支持拖拽、缩放、旋转等操作。
功能特性
- 🎨 可视化模板设计
- 📝 文本组件
- 📊 条形码组件
- 🔲 二维码组件
- 🖼️ 图片组件(支持上传)
- 📐 矩形框组件
- ➖ 线段组件
- 🎯 组件拖拽、缩放、旋转
- 📋 属性面板配置
- 🖼️ 模板预览导出
- 🔧 双重组件控制
安装和使用
npm install template-designer<template>
<TemplateDesigner
:templateData="templateData"
:config="config"
:options="{ fields }"
template-type="lodop"
/>
</template>
<script setup>
import { TemplateDesigner } from 'template-designer'
// templateData必须包含width,height字段且值均大于0
const templateData = ref({
width: 100,
height: 30,
printWidth: 103,
printHeight: 40,
items: []
})
const config = ref({
// 组件显示配置
})
const fields = ref([
{ label: '商品条码', value: 'goodsSn' },
{ label: '商品名称', value: 'goodsName', {
// 配置动态联动属性 同 /props/(lodop或rfid).js中的propertyPanel配置 可多级
// 例如
propertyPanel: {
// 必选
prop: 'xxx',
// 必选
label: 'xxx',
// 必选
type: 'select',
// 必选
default: '',
// 必选 属性布局 full-独占一行 half-半行
layout: 'full',
// 可选 是否多选
multiple: false,
// 可选 属性描述(label后显示问好图标,hover显示)
desc: '',
// 可选 是否隐藏
hide: false,
// type为select必选
options: [
{
label: 'xxx',
value: 'xxx',
propertyPanel: {
prop: 'xxx',
label: 'xxx',
type: 'select',
default: '',
layout: 'full',
options: [
...
]
}
},
...
]
}
}, ...}
])
</script>配置说明
双重组件控制功能
功能说明
组件库现在支持双重控制来隐藏/显示组件:
- 通过config参数控制
- 通过配置文件控制 如果配置文件中没有某个组件的配置,则不展示该组件
属性面板布局控制功能
功能说明
组件库现在支持通过配置文件控制属性面板的布局:
- 独占一行(
layout: 'full')- 属性项占满整行宽度 - 占半行(
layout: 'half')- 属性项占半行宽度,可以并排显示,自动换行 - 默认布局 - 根据属性类型自动判断布局方式
使用方法
1. 通过config参数控制
const config = {
// 隐藏特定组件
text: { hidden: true }, // 隐藏文本组件
barcode: { hidden: true }, // 隐藏一维码组件
image: { hidden: true }, // 隐藏图片组件
rectangle: { hidden: true }, // 隐藏矩形框组件
// 设计区域背景 默认rgba(0, 0, 0, .05) 须为css支持的字符
designBackground: ''
}
// 使用组件
<TemplateDesigner :config="config" />2. 通过配置文件控制
在 src/js/config/props/ 目录下创建配置文件,只包含需要显示的组件:
// src/js/config/props/xxx.js
export default {
text: {
// 文本组件配置
},
barcode: {
// 一维码组件配置
}
...
}系统会自动根据 template-type 动态加载对应的配置文件:
// src/js/config/index.js
export async function getPropsConfig(type) {
try {
// 直接通过type对应文件名动态导入
const config = await import(`./props/${type}.js`)
return config.default
} catch (error) {
// 如果指定的配置文件不存在,返回lodop配置作为默认值
const defaultConfig = await import('./props/lodop.js')
return defaultConfig.default
}
}3. 双重控制示例
<template>
<TemplateDesigner
:template-type="currentTemplateType"
:config="componentConfig"
/>
</template>
<script setup>
import { ref } from 'vue'
const currentTemplateType = ref('rfid') // 使用rfid配置文件
const componentConfig = ref({
text: { hidden: false }, // 显示文本组件
barcode: { hidden: true }, // 隐藏一维码组件
// 注意:即使config中设置了显示,如果配置文件中没有该组件,仍然不会显示
})
// 切换模板类型
const changeTemplateType = (type) => {
currentTemplateType.value = type
}
</script>实际效果
- LODOP配置:显示所有组件(text, barcode, qrcode, image, rectangle, line)
- RFID配置:显示所有组件(text, barcode, qrcode, image)
支持的模板类型
lodop- 默认配置,包含所有组件(对应lodop.js)rfid- RFID标签配置,包含所有组件(对应rfid.js)- 其他任何类型 - 系统会尝试加载
./props/{type}.js文件,如果不存在则使用lodop配置作为默认值
组件类型
text- 文本组件barcode- 一维码组件qrcode- 二维码组件image- 图片组件rectangle- 矩形框组件line- 线段组件
属性面板布局控制功能
功能说明
组件库现在支持通过配置文件控制属性面板的布局:
- 独占一行(
layout: 'full')- 属性项占满整行宽度 - 占半行(
layout: 'half')- 属性项占半行宽度,可以并排显示,自动换行 - 默认布局 - 根据属性类型自动判断布局方式
使用方法
1. 在配置文件中设置布局
// src/js/config/props/rfid.js
export default {
text: {
propertyPanel: [
{
prop: 'Title',
label: '标题',
default: '',
layout: 'full' // 独占一行
},
{
prop: 'FontName',
label: '字体名称',
type: 'select',
options: [...],
default: '黑体',
layout: 'half' // 占半行
},
{
prop: 'FontSize',
label: '字体大小',
type: 'number',
min: 1,
max: 100,
default: 10,
layout: 'half' // 占半行
}
]
}
}2. 布局类型说明
layout: 'full'- 属性项独占一行,适合文本输入、文件上传等需要更多空间的属性layout: 'half'- 属性项占半行,适合下拉选择、数字输入等紧凑型属性- 不设置layout - 系统根据属性类型自动判断:
text、file、textarea类型默认独占一行- 其他类型默认占半行
3. 布局效果
- 独占一行:属性项占满整行宽度,垂直排列
- 占半行:两个属性项并排显示,自动换行,形成网格布局
- 响应式:在不同屏幕尺寸下自动调整布局
图片上传
在配置中添加图片上传
// 隐藏特定组件
const config = {
...
image: { request: file => {
// 上传
....
return url // 上传完的url
}}
...
}
// 使用组件
<TemplateDesigner :config="config" />注意事项
1、控件中的字段(FieldName)只选中一个值为字符串,如果选中多个则为字符串数组,使用时注意兼容
2、当前模板中控件的旋转中心为控件的中心,每个组件的数据都包含x1,y1,为左上角旋转之后的实时坐标,旋转角度为顺时针
字段替换规则
- 适用组件:text、barcode、qrcode。
- FieldName 支持 string 或数组:
- string:从
printData[key]取值 - array:从
printData逐个取值,使用组件FieldConnector连接(默认空格)
- string:从
- 覆盖策略:导出前始终用打印数据覆盖组件测试值:
- text → 覆盖
Text - barcode → 覆盖
BarcodeValue - qrcode → 覆盖
QRCodeValue
- text → 覆盖
渲染导出工具:renderTemplateToPdfBase64
提供一个独立工具,将“模板数据 + 打印数据”渲染为 PDF 或 PNG,并返回 base64 或 dataURL
导入
import { renderTemplateToPdfBase64 } from 'template-designer'函数签名
async function renderTemplateToPdfBase64(
template: object, // 模板数据(同设计器使用的数据结构)
printData: Record<string, any>, // 打印数据(key -> value)
options?: {
page?: { widthMm?: number; heightMm?: number; marginMm?: number } // (可选)默认打印宽高
returnType?: 'base64' | 'dataUrl' // (可选)默认 'base64'
format?: 'pdf' | 'png' // (可选)默认 'pdf';png 可保留透明背景
pdf?: {
orientation?: 'portrait' | 'landscape' // (可选)默认自动
transparent?: boolean // (可选)是否保留透明背景(仅对 pdf 内嵌图像生效)
quality?: number // (可选)0~1(jpeg质量,透明=false 时生效,默认 0.85)
scale?: number // (可选)html2canvas 放大倍数,建议 1.5~2.5
compress?: boolean // (可选)jsPDF 压缩,默认 true
}
}
): Promise<string>基础用法(导出 PDF,返回 base64)
const pdfBase64 = await renderTemplateToPdfBase64(template, printData, {
page: { widthMm: 103, heightMm: 40 },
returnType: 'base64',
pdf: {
orientation: 'landscape',
transparent: false, // 若不需要透明,可关闭以减小体积
quality: 0.8, // 仅非透明时生效(jpeg质量)
scale: 2, // 1.5~2.5 间调节清晰度与体积
compress: true
}
})体积优化建议
- 不需要透明背景时,
transparent=false+quality≈0.8+scale≈2,可显著减小体积仍保持清晰。 - 需要极致清晰时提高
scale;若体积过大,适当降低quality。
条形码和二维码生成工具
提供独立的条形码和二维码生成函数,可在组件外部使用。
generateBarcode - 条形码生成
导入
import { generateBarcode } from 'template-designer'函数签名
async function generateBarcode(
text: string, // 要编码的文本内容
options?: {
CodeType?: string // 条形码格式,可选'CODE128'|'CODE39'|'EAN13'|'EAN8'|'UPC'|'ITF14'|'MSI'|'pharmacode'|'codabar',默认'CODE128'
width?: number // 条形码宽度(毫米),默认50
height?: number // 条形码高度(毫米),默认15
LineColor?: string // 条形码颜色,默认'#000000'
background?: string // 背景色,默认'#ffffff'
displayValue?: boolean // 是否显示文本,默认false
textAlign?: string // 文本对齐,可选'left'|'center'|'right',默认'center'
textPosition?: string // 文本位置,可选'bottom'|'top',默认'bottom'
textMargin?: number // 文本边距(毫米),默认2
font?: string // 字体,默认'monospace'
fontSize?: number // 字体大小(毫米),默认5
outputFormat?: string // 输出格式,可选'png'|'jpeg'|'svg',默认'png'
quality?: number // 图片质量(0-1),仅对jpeg有效,默认0.95
returnDataUrl?: boolean // 是否返回完整dataUrl,默认true
dpi?: number // DPI值,默认300
}
): Promise<string> // 返回base64格式的图片数据或dataUrl使用示例
// 基础用法
const barcodeDataUrl = await generateBarcode('1234567890', {
CodeType: 'CODE128',
width: 50,
height: 15,
displayValue: true
})
// 使用返回的dataUrl
const img = document.createElement('img')
img.src = barcodeDataUrl
document.body.appendChild(img)
// 自定义样式
const customBarcode = await generateBarcode('ABC123', {
CodeType: 'CODE39',
width: 60,
height: 20,
LineColor: '#FF0000',
background: '#FFFF00',
displayValue: true,
textAlign: 'center',
fontSize: 6,
outputFormat: 'png',
dpi: 300
})支持的条形码格式
CODE128- 支持ASCII字符,最大80个字符(默认)CODE39- 支持大写字母、数字、特殊字符,最大43个字符EAN13- 13位数字,商品条码EAN8- 8位数字,商品条码UPC- 12位数字,商品条码ITF14- 14位数字,物流条码MSI- 数字,最大20位pharmacode- 数字,最大6位,药品条码codabar- 支持数字、字母、特殊字符,最大20个字符
generateQRCode - 二维码生成
导入
import { generateQRCode } from 'template-designer'函数签名
async function generateQRCode(
text: string, // 要编码的文本内容
options?: {
width?: number // 二维码宽度(毫米),默认50
height?: number // 二维码高度(毫米),默认50
QRCodeForeground?: string // 前景色(二维码颜色),默认'#000000'
QRCodeBackground?: string // 背景色,默认'#ffffff'
QRCodeErrorLevel?: string // 错误纠正级别,可选'L'|'M'|'Q'|'H',默认'M'
margin?: number // 边距(毫米),默认0
format?: string // 输出格式,可选'png'|'jpeg'|'svg',默认'png'
quality?: number // 图片质量(0-1),仅对jpeg有效,默认0.9
returnDataUrl?: boolean // 是否返回完整dataUrl,默认true
dpi?: number // DPI值,默认96
}
): Promise<string> // 返回base64格式的图片数据或dataUrl使用示例
// 基础用法
const qrcodeDataUrl = await generateQRCode('https://example.com', {
width: 50,
height: 50,
QRCodeErrorLevel: 'M'
})
// 使用返回的dataUrl
const img = document.createElement('img')
img.src = qrcodeDataUrl
document.body.appendChild(img)
// 自定义样式
const customQRCode = await generateQRCode('Hello World', {
width: 60,
height: 60,
QRCodeForeground: '#0000FF',
QRCodeBackground: '#FFFFFF',
QRCodeErrorLevel: 'H', // 高错误纠正级别
margin: 2,
format: 'png',
dpi: 300
})
// 生成SVG格式
const svgQRCode = await generateQRCode('SVG格式二维码', {
width: 50,
height: 50,
format: 'svg',
returnDataUrl: true
})错误纠正级别说明
L- 低(约7%的错误可被纠正)M- 中(约15%的错误可被纠正,默认)Q- 四分之一(约25%的错误可被纠正)H- 高(约30%的错误可被纠正)
开发
npm run dev
npm run build许可证
MIT
