自定义元素插件
约 1108 字大约 4 分钟
...
2026-09-29
说明
元素插件 用于给设计器新增打印元素。
例如: bwip-js 条码/二维码、echarts 图表、骑缝章等等。
主要使用两个 hook:
init:注册元素参数面板(Config)与元素类型(ElementTypes)createPrintElement:按ele.type返回继承BasePrintElement的元素类,不匹配返回null
创建工程
npx create-sv-print-plugin init项目结构与插件开发入门一致,重点目录:
my-ele-plugin/
├── package.json
├── vite.config.ts
└── src/
├── index.ts # 插件入口:组装 hooks
├── types.ts # 类型定义
├── config.ts # 元素参数面板配置(hiprint.setConfig)
├── options.ts # 元素参数定义(Config.registerItems)
└── hooks/
├── init.ts # init hook:注册参数 + 元素类型
└── createPrintElement.ts # createPrintElement hook:元素类实现init:注册参数与元素类型
src/hooks/init.ts
import type { HookOptions } from 'sv-print';
import PrintElementConfig from '../config';
import { getPrintElementOptions } from '../options';
const initHook = (): HookOptions => ({
hook: 'init',
name: 'add style',
priority: 1,
run: ({ Config, ElementTypes, hiprint }) => {
// 1. 插入元素参数(属性面板可配置项)
Config.registerItems([...getPrintElementOptions()]);
// 2. 元素参数面板配置(tab 分组、默认值等)
hiprint.setConfig(PrintElementConfig);
// 3. 注册元素类型
ElementTypes.addPrintElementType({
tid: 'defaultModule.myEle(自定义)', // 唯一 key
type: 'myEle', // 元素类型, createPrintElement 按它分发
title: '自定义元素',
options: {
width: 160,
height: 40,
textAlign: 'center',
},
});
// 4. 挂到设计器左侧"插件"分组(不存在则新建)
const type = ElementTypes.allElementTypes.find((t) => t.tid === 'defaultModule.myEle(自定义)');
const groups = ElementTypes.getElementTypeGroups('defaultModule');
const pluginGroup = groups.find((e) => e.name == '插件');
if (pluginGroup) {
pluginGroup.printElementTypes.push(type);
} else {
groups.splice(1, 0, { name: '插件', printElementTypes: [type] });
}
},
});
export default initHook;createPrintElement:实现元素类
返回继承 BasePrintElement 的类;ele.type 不匹配时必须返回 null,否则会影响其他元素。
src/hooks/createPrintElement.ts
import type { HookOptions } from 'sv-print';
const createPrintElementHook = (): HookOptions => ({
hook: 'createPrintElement',
name: 'myEle',
priority: 1,
run: ({ Config, BasePrintElement, Options, Supper, ele, eleOpt }) => {
// 只处理自己的元素类型
if (ele.type !== 'myEle') return null; // 不匹配必须返回 null, 否则会影响其他元素
class MyPrintElement extends BasePrintElement {
constructor(config: any, options: any) {
super(config);
this.options = new Options(options);
this.options.setDefault(
new Options(Config[ele.type].default).getPrintElementOptionEntity(),
);
}
getTitle() {
return this.options.title || this.printElementType.title || '';
}
// 设计态:options 变化后更新设计视图
updateDesignViewFromOptions() {
if (this.designTarget) {
const data = this.getData();
this.css(this.designTarget, data);
this.updateTarget(this.designTarget, this.getTitle(), data);
}
}
// 核心:渲染元素内容(设计态与打印态共用)
updateTarget(target: any, title: any, data: any) {
const formatter = this.getFormatter();
let text = data;
if (!this.getField()) {
text = formatter ? formatter(title, title, this.options) : title;
} else if (formatter) {
text = formatter(title, data, this.options);
}
target.find('.hiprint-printElement-content').html(text || '');
}
// 创建元素 DOM 结构
createTarget(title: any, data: any) {
const target = globalThis.$(
'<div class="hiprint-printElement" style="position: absolute;">' +
'<div class="hiprint-printElement-content" style="height:100%;width:100%"></div></div>',
);
this.updateTarget(target, title, data);
return target;
}
// 拖拽缩放后重新渲染
onResize(e: any, n: any, i: any, o: any, r: any) {
super.onResize(e, n, i, o, r);
this.updateTarget(this.designTarget, this.getTitle(), this.getData());
}
// 可拖拽调整的边角
getReizeableShowPoints() {
return ['r', 's', 'e', 'n', 'w', 'ne', 'nw', 'se', 'sw'];
}
// 打印态 html 输出
getHtml(paper: any, templateData: any, cb?: any) {
return this.getHtml2(paper, templateData, cb);
}
}
return MyPrintElement; // 返回元素类, 而非实例
},
});
export default createPrintElementHook;插件入口
src/index.ts
import type { PluginOptions } from 'sv-print';
import { initHook, createPrintElementHook } from './hooks/index';
export default function plugin(options = {}): PluginOptions {
return {
name: 'myEle',
description: '新增打印元素 myEle',
hooks: [initHook(options), createPrintElementHook(options)], // 多个 hook 组合使用
leastHiprintVersion: '0.1.8',
};
}使用
import pluginMyEle from './index';
// 须在创建模板/打开设计器之前注册
await hiprint.register({ plugins: [pluginMyEle({})] });
// 注册后设计器左侧"插件"分组出现"自定义元素",拖入模板即可更多参考
plugin-ele-bwip 中还有这些进阶实现,可直接阅读源码:
config.ts:属性面板 tab 分组(基础/条码 等页签)options.ts:getPrintElementOptions定义元素参数项type-barcode.ts/type-qrcode.ts:Config.registerItems自定义下拉选项- 多元素类型分发:
ELEMENT_CONFIGS按ele.type复用同一套元素类
版权所有
版权归属:sv-print
