@kuangyep/templates-package
v1.0.3
Published
基于 Vue 3 + Vite Library Mode 的证书/打印模板组件库。 当前主要产物是两个 Custom Element:
Readme
Templates Web Component 组件库
基于 Vue 3 + Vite Library Mode 的证书/打印模板组件库。
当前主要产物是两个 Custom Element:
canvas-certificate(Fabric 渲染证书)hiprint-template(hiprint 打印模板)
安装
npm i @kuangyep/templates-package fabric说明:
fabric是peerDependencies,由宿主项目提供。hiprint-template依赖全局hiprint/jQuery(见下方说明)。
导出入口
package.json 当前导出:
@kuangyep/templates-package->fabricDesign@kuangyep/templates-package/fabricDesign@kuangyep/templates-package/hiprintDesign
快速使用
1) Fabric 证书组件(推荐)
Vue 3 项目中,在宿主入口注册组件:
import '@kuangyep/templates-package/fabricDesign'如果宿主是 Vue 3 + Vite,建议在 vite.config.ts 中把组件声明为 Custom Element:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) =>
tag === 'canvas-certificate' || tag === 'hiprint-template'
}
}
})
]
})Vue 页面中使用:
<template>
<canvas-certificate
template-id="tpl_001"
template-api="/api/certificate/template/detail"
:data.prop="certificateData"
></canvas-certificate>
</template>
<script setup lang="ts">
const certificateData = {
name: '张三',
cardNo: '510...'
}
</script>说明:
template-id、template-api这类字符串可以直接按 attribute 传递。data如果是对象,Vue 3 中推荐使用:data.prop="certificateData",确保值按 DOM property 传给 Web Component。- 如果传 JSON 字符串,也可以直接写
data='{"name":"张三"}'。
Vue 2(Webpack / Vite)自定义元素配置
Vue 2 中不需要 isCustomElement,统一在 main.js 里配置 ignoredElements:
import Vue from 'vue'
import App from './App.vue'
// 根包当前等价于 fabricDesign
import '@kuangyep/templates-package'
// 或者显式使用:import '@kuangyep/templates-package/fabricDesign'
Vue.config.ignoredElements = ['canvas-certificate']
// 若同时使用打印组件可加上:'hiprint-template'
// Vue.config.ignoredElements = ['canvas-certificate', 'hiprint-template']
new Vue({
render: h => h(App)
}).$mount('#app')说明:
- Vue 2 + Webpack(Vue CLI)和 Vue 2 + Vite 都是这套配置,无需额外改打包器参数。
ignoredElements的作用是告诉 Vue 2 这些标签是 Custom Element,避免“Unknown custom element”警告。- 如果宿主是老构建链路(如 Webpack2/Babel6)并报
Unexpected token ?,请使用下方build:legacy产物(降级到es2015)。
2) hiprint 组件
在宿主入口注册组件:
import '@kuangyep/templates-package/hiprintDesign'并确保宿主已提供全局依赖(CDN 顺序):
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/socket.io-client@4/dist/socket.io.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-plugin-hiprint@latest/dist/vue-plugin-hiprint.js"></script>print-lock.css 已由组件构建时内联注入,宿主无需额外再引入该 CSS。
Vue 页面使用:
<template>
<hiprint-template :data.prop="printData"></hiprint-template>
</template>
<script setup lang="ts">
const printData = {
title: '道路运输服务',
tablelist: [{ love: '篮球', sex: '男' }]
}
</script>组件 API
canvas-certificate
Props:
template-id: string | number(必填)template-api: string(默认/api/certificate/template/detail)data: object | string(支持对象或 JSON 字符串)
暴露方法:
toDataURL(multiplier?: number):导出 PNG dataURL(默认2)reloadTemplate():重新拉取模板并渲染
接口返回支持以下结构之一:
{ templateJson: {...} }{ template: {...} }{ data: { templateJson: {...} } }{ data: { template: {...} } }{ data: {...} }
Vue2 / Vue3 调用导出方法
canvas-certificate 是 Web Component,导出图片时直接拿到元素实例调用:
el.toDataURL(multiplier?)
Vue 3(<script setup>)
<template>
<canvas-certificate
ref="certRef"
template-id="tpl_001"
template-api="/api/certificate/template/detail"
:data.prop="certificateData"
/>
<button @click="onExport">导出图片</button>
</template>
<script setup lang="ts">
import { ref } from 'vue'
type CanvasCertificateEl = HTMLElement & {
toDataURL?: (multiplier?: number) => string
}
const certRef = ref<CanvasCertificateEl | null>(null)
const certificateData = { name: '张三', cardNo: '510...' }
const onExport = async () => {
await customElements.whenDefined('canvas-certificate')
const dataUrl = certRef.value?.toDataURL?.(2)
if (!dataUrl) return
const link = document.createElement('a')
link.href = dataUrl
link.download = `certificate-${Date.now()}.png`
link.click()
}
</script>Vue 2(Options API)
<template>
<div>
<canvas-certificate
ref="certRef"
template-id="tpl_001"
template-api="/api/certificate/template/detail"
:data="dataJson"
/>
<button @click="onExport">导出图片</button>
</div>
</template>
<script>
export default {
data() {
return {
certificateData: { name: '张三', cardNo: '510...' }
}
},
computed: {
dataJson() {
return JSON.stringify(this.certificateData)
}
},
methods: {
async onExport() {
await customElements.whenDefined('canvas-certificate')
const el = this.$refs.certRef
const dataUrl = el && el.toDataURL ? el.toDataURL(2) : ''
if (!dataUrl) return
const link = document.createElement('a')
link.href = dataUrl
link.download = `certificate-${Date.now()}.png`
link.click()
}
}
}
</script>说明:
multiplier越大,导出越清晰,文件也会更大(常用1~2)。- Vue 2 场景建议
data传 JSON 字符串,或在mounted后通过this.$refs.certRef.data = {...}赋值。
hiprint-template
Props:
data: object | string
暴露方法:
print():调用 hiprint 打印
传参说明(重点)
在 Vue 3 模板中:
data如果是对象,推荐使用.prop修饰符按 DOM property 传值。
<canvas-certificate
template-id="tpl_001"
template-api="/api/certificate/template/detail"
:data.prop="certificateData"
></canvas-certificate>const certificateData = {
name: '张三'
}说明:
:data="certificateData"在 Vue 3 + Web Component 场景下不够稳定,不建议作为 README 推荐写法。:data.prop="certificateData"、el.data = {...}、data='{"name":"张三"}'都是支持的。
在纯 HTML 中:
- attribute 只能是字符串,所以
data通常传 JSON 字符串。
<canvas-certificate data='{"name":"张三"}'></canvas-certificate>如果想传对象,请用 DOM property:
<canvas-certificate id="cert"></canvas-certificate>
<script>
const el = document.getElementById('cert')
el.templateId = 'tpl_001'
el.templateApi = '/api/certificate/template/detail'
el.data = { name: '张三' }
</script>构建命令
# 启动设计器开发环境
npm run dev
# 构建全部模板入口(扫描 src/templates/*/main-ce.ts)
npm run build
# 打包当前项目(应用构建,入口 src/main.js,输出 dist)
npm run prod
# 构建单个目标(默认会回退到 fabricDesign)
npm run build:single -- fabricDesign
npm run build:single -- hiprintDesign
# 构建 Vue2/vue3 legacy 产物(降级语法到 es2015,避免 ?. / ??)
npm run build:legacy
# 构建单个 legacy 目标
npm run build:single:legacy -- fabricDesign
# 预览
npm run preview本地测试(项目服务页面 + mock 接口)
# 1) 启动 Vite 项目服务(页面)
npm run dev
# 2) 启动 mock 接口服务
npm run test:mock启动后:
- 页面(项目服务):
http://localhost:5173/webview/certificate.html - 健康检查(mock):
http://localhost:8090/health - 模板接口(mock):
POST/GET http://localhost:8090/api/certificate/template/detail
说明:
public/webview/certificate.html由 Vite 直接托管,不再由 node mock 服务提供 HTML。- 开发模式下,
/api/certificate/*会自动代理到http://127.0.0.1:8090(可用MOCK_API_TARGET覆盖)。 - 可通过 URL 参数覆盖模板接口:
/webview/certificate.html?templateApi=https://你的域名/api/certificate/template/detail - 导出页在小程序中会按
fileIndex.html规则自动选择上传接口:env=prod->https://chengkebus.com/safety-certificate/admin/api/v1/region/a/uploadFile其他环境 ->http://182.140.209.47:8081/safety-certificate/admin/api/v1/region/a/uploadFile
WebView 预览与小程序接入
public/webview/certificate.html 预览地址:
- 本机:
http://localhost:5173/webview/certificate.html - 真机:
http://你的局域网IP:5173/webview/certificate.html
常用 URL 参数:
templateApi:模板接口地址env:上传环境(prod或其他)redirectPage:小程序回跳页面(推荐方式)resultPrefix:redirect 回传参数前缀(默认cert)uploadFieldName:上传接口文件字段名(默认file)
小程序方式一(推荐):redirect 回传
小程序 web-view 的 src 传 redirectPage:
http://10.50.40.112:5173/webview/certificate.html?env=test&redirectPage=/pages/webview/indexH5 会在导出完成后 redirectTo(redirectPage),并把结果拼到 query。
回传参数(默认前缀 cert):
certStatuscertUrlcertErrorcertFileNamecertActioncertTs
小程序接收(onLoad):
onLoad((options) => {
if (options.certStatus === 'success' && options.certUrl) {
// options.certUrl 就是回传的图片 URL
} else if (options.certStatus === 'fail') {
// options.certError
}
})小程序方式二(兼容):postMessage 回传
如果未传 redirectPage 或 redirect 失败,H5 会回退到 postMessage + navigateBack。
小程序接收(@message):
const onMessage = (e: any) => {
const res = e?.detail?.data?.[0]
if (!res) return
if (res.action === 'exportComplete' && res.status === 'success') {
// res.url 就是回传的图片 URL
} else {
// res.error
}
}postMessage 回传结构:
action: 'exportComplete'status: 'success' | 'fail'url?: stringerror?: stringfileName?: string
真机调试注意:
web-view在手机端不能使用localhost,请改为电脑局域网 IP,例如http://10.50.40.112:5173/webview/certificate.html
mock 模板目录:
test-app/mock-templates/*.json(例如tpl_001.json)
发布
# 默认发布(legacy 产物,Vue2 友好)
npm run pub
# 显式发布 legacy 产物(与 pub 等价)
npm run pub:legacy当前发布配置:
- registry:
https://registry.npmjs.org - 模板构建输出目录:
templatedist - 项目默认构建输出目录:
dist - 发布文件白名单:
templatedist/*.js、templatedist/*.css(不会上传dist/stats.html)
若账号开启了 npm 2FA,发布时需要 OTP:
npm publish --registry=https://registry.npmjs.org --access public --otp=123456目录结构
shared-widget/
├─ src/
│ ├─ templates/
│ │ ├─ fabricDesign/
│ │ │ ├─ main-ce.ts
│ │ │ └─ canvasCertificate.vue
│ │ └─ hiprintDesign/
│ │ ├─ main-ce.ts
│ │ └─ HiprintTemplate.vue
│ ├─ views/ # 设计器与预览页
│ └─ controls/ # 设计器控件
├─ scripts/
│ ├─ build-templates.js
│ └─ build-single.js
├─ public/
│ └─ webview/
│ ├─ certificate.html
│ └─ uni.webview.1.5.6.js
├─ test-app/
│ ├─ server.js
│ └─ mock-templates/
├─ dist/
├─ templatedist/ # 模板构建产物(js/css)
└─ package.json