在后台管理系统中,订单打印功能往往需要根据业务数据动态生成。传统的静态打印模板无法满足这种需求,而vue-plugin-hiprint提供了完美的解决方案。我们先来看一个典型场景:当用户在前端修改了订单数量时,打印预览内容需要实时更新。
实现这一功能的关键在于建立响应式数据源与打印模板的关联。首先需要在Vue组件中定义数据模型:
javascript复制const orderData = reactive({
orderNo: '20230815001',
customerName: '张三',
items: [
{ name: '商品A', price: 99, quantity: 2 },
{ name: '商品B', price: 199, quantity: 1 }
],
total: 0
})
// 计算总价
watchEffect(() => {
orderData.total = orderData.items.reduce((sum, item) => sum + item.price * item.quantity, 0)
})
接下来需要改造之前创建的打印模板,使其能够绑定动态数据。在模板设计阶段,我们需要使用特殊的字段语法:
javascript复制// 在模板设计完成后保存的JSON中
{
"fields": [
{
"type": "text",
"options": {
"field": "orderNo", // 绑定orderData.orderNo
"text": "{orderNo}" // 模板语法
}
},
{
"type": "table",
"options": {
"fields": [
{ "field": "name", "title": "商品名称" },
{ "field": "price", "title": "单价" },
{ "field": "quantity", "title": "数量" }
],
"data": "items" // 绑定数组数据
}
}
]
}
动态数据绑定的核心价值在于能够实时预览数据变化。我们需要在模板实例上添加更新方法:
javascript复制// 在组件中暴露模板实例
const hiprintTemplate = ref()
// 更新模板数据的方法
const updatePreview = () => {
if (hiprintTemplate.value) {
hiprintTemplate.value.update(orderData)
}
}
// 监听数据变化自动更新
watch(orderData, updatePreview, { deep: true })
实际开发中可能会遇到一些常见问题:
reactive或ref包装数据对象一个完整的订单打印组件可能包含这些方法:
javascript复制// 打印当前订单
const handlePrint = () => {
hiprintTemplate.value.print(orderData)
}
// 导出PDF
const exportPDF = async () => {
const pdfUrl = await hiprintTemplate.value.toPdf(orderData)
const link = document.createElement('a')
link.href = pdfUrl
link.download = `订单_${orderData.orderNo}.pdf`
link.click()
}
对于复杂的业务场景,我们需要掌握更多模板设计技巧:
条件显示:某些字段只在特定条件下显示
javascript复制{
"options": {
"field": "discount",
"visible": "discount > 0" // 当折扣大于0时显示
}
}
自定义样式:根据数据值动态改变样式
javascript复制{
"options": {
"field": "total",
"styles": {
"color": "total > 1000 ? 'red' : 'black'",
"fontWeight": "total > 5000 ? 'bold' : 'normal'"
}
}
}
嵌套数据结构:处理对象嵌套的情况
javascript复制{
"options": {
"field": "customer.address.city",
"text": "{customer.address.city}"
}
}
对于表格数据,还可以添加自定义列:
javascript复制{
"type": "table",
"options": {
"fields": [
// 常规字段...
{
"field": "_operation", // 自定义字段
"title": "操作",
"formatter": (value, row, index) => {
return `<button onclick="removeItem(${index})">删除</button>`
}
}
]
}
}
在实际项目中,打印功能可能会遇到性能问题,特别是在处理大量数据时。以下是几个优化建议:
javascript复制hiprintTemplate.value.design("#container", {
grid: true,
virtualScroll: true,
scrollStep: 50 // 每次滚动的像素数
})
javascript复制{
"type": "image",
"options": {
"field": "product.image",
"lazyLoad": true,
"placeholder": "/loading.png"
}
}
javascript复制// 主模板
hiprintTemplate.value.loadTemplate('base')
// 动态加载子模板
const loadSubTemplate = async (name) => {
const res = await fetch(`/templates/${name}.json`)
hiprintTemplate.value.addSubTemplate(await res.json())
}
javascript复制// 保存模板到本地存储
const saveTemplate = () => {
const templateJson = hiprintTemplate.value.getJson()
localStorage.setItem('orderTemplate', JSON.stringify(templateJson))
}
// 初始化时加载缓存
onMounted(() => {
const cached = localStorage.getItem('orderTemplate')
if (cached) {
hiprintTemplate.value.update(JSON.parse(cached))
}
})
在项目实战中,我遇到过几个典型问题及解决方案:
wordBreak: 'break-all'解决