如何在vue项目中监测数据变化来实现自动打印
怎样在vue项目中监测数据变化来实现自动打印一、初代版本初代版本中,并没有要求自动打印,要实现的是手动打印,这个功能没啥可说的,直接用vue-print-nb这个插件就OK,实现方式也很简单,我这里简单说一下,网上很多类似教程1、安装npm install vue-print-nb --save2、引入全局如下在main.js中引入,非全局不用说了把,引入直接用就行import Print fro
怎样在vue项目中监测数据变化来实现自动打印
一、初代版本
初代版本中,并没有要求自动打印,要实现的是手动打印,这个功能没啥可说的,直接用
vue-print-nb这个插件就OK,实现方式也很简单,我这里简单说一下,网上很多类似教程
1、安装
npm install vue-print-nb --save
2、引入
全局如下在main.js中引入,非全局不用说了把,引入直接用就行
import Print from ‘vue-print-nb’
Vue.use(Print);
3、查找id方式打印
<div id="printMe" >
<p>打印内容</p>
</div>
<button v-print="'#printMer'">打印</button>
其实主要在于v-print
4、对象方式打印
<button v-print="printObj">Print local range</button>
<div id="printMe" style="background:red;">
<p>葫芦娃,葫芦娃</p>
<p>一根藤上七朵花 </p>
</div>
这里是html
export default {
data() {
return {
printObj: {
id: "printMe",
popTitle: 'good print',
extraCss: 'https://www.google.com,https://www.google.com',
extraHead: '<meta http-equiv="Content-Language"content="zh-cn"/>'
}
};
}
}
这里是方法
id:*必填需部分打印输入的ID
standard:文档类型,默认是HTML5,可选html5,loose,strict
extraHead:附加到head标签的附加标签,以逗号分隔
extraCss:附加链接连接,以逗号分隔
popTitle:标题显示标题
endCallback():打印后的回调事件
这个就不过多介绍了,用这个插件写打印存在一个问题,那就是没法关闭预览,所以在第二版本时我进行了改变
二、更改版本
1、打印插件
CLodop云打印
2、打印方法编写
2-1、官网下载lodopFuncs.js(这个名字后面可以改,主要是里面的内容)
2-2、下载完成之后稍微改造一下(其实就是导出方法,其余不变)
var CreatedOKLodop7766 = null
//= ===判断是否需要安装CLodop云打印服务器:====
export function needCLodop() { //就改这里就好
try {
var ua = navigator.userAgent
if (ua.match(/Windows\sPhone/i) != null) return true
if (ua.match(/iPhone|iPod/i) != null) return true
if (ua.match(/Android/i) != null) return true
if (ua.match(/Edge\D?\d+/i) != null) return true
var verTrident = ua.match(/Trident\D?\d+/i)
var verIE = ua.match(/MSIE\D?\d+/i)
var verOPR = ua.match(/OPR\D?\d+/i)
var verFF = ua.match(/Firefox\D?\d+/i)
var x64 = ua.match(/x64/i)
if (verTrident == null && verIE == null && x64 !== null) {
return true
}
if (verFF !== null) {
verFF = verFF[0].match(/\d+/)
if (verFF[0] >= 42 || x64 !== null) return true
} else if (verOPR !== null) {
verOPR = verOPR[0].match(/\d+/)
if (verOPR[0] >= 32) return true
} else if (verTrident == null && verIE == null) {
var verChrome = ua.match(/Chrome\D?\d+/i)
if (verChrome !== null) {
verChrome = verChrome[0].match(/\d+/)
if (verChrome[0] >= 42) return true
}
}
return false
} catch (err) {
return true
}
}
//= ===页面引用CLodop云打印必须的JS文件:====
if (needCLodop()) {
var head =
document.head ||
document.getElementsByTagName('head')[0] ||
document.documentElement
var oscript = document.createElement('script')
oscript.src = 'http://localhost:8000/CLodopfuncs.js?priority=1'
head.insertBefore(oscript, head.firstChild)
// 引用双端口(8000和18000)避免其中某个被占用:
oscript = document.createElement('script')
oscript.src = 'http://localhost:18000/CLodopfuncs.js?priority=0'
head.insertBefore(oscript, head.firstChild)
}
//= ===获取LODOP对象的主过程:====
export function getLodop(oOBJECT, oEMBED) {
var strHtmInstall =
"<br><font color='#FF00FF'>打印控件未安装!点击这里<a href='http://www.lodop.net/download.html'>执行安装</a>,安装后请刷新页面或重新进入。</font>"
var strHtmUpdate =
"<br><font color='#FF00FF'>打印控件需要升级!点击这里<a href='http://www.lodop.net/download.html'>执行升级</a>,升级后请重新进入。</font>"
var strHtm64_Install =
"<br><font color='#FF00FF'>打印控件未安装!点击这里<a href='http://www.lodop.net/download.html' >执行安装</a>,安装后请刷新页面或重新进入。</font>"
var strHtm64_Update =
"<br><font color='#FF00FF'>打印控件需要升级!点击这里<a href='http://www.lodop.net/download.html'>执行升级</a>,升级后请重新进入。</font>"
var strHtmFireFox =
"<br><br><font color='#FF00FF'>(注意:如曾安装过Lodop旧版附件npActiveXPLugin,请在【工具】->【附加组件】->【扩展】中先卸它)</font>"
var strHtmChrome =
"<br><br><font color='#FF00FF'>(如果此前正常,仅因浏览器升级或重安装而出问题,需重新执行以上安装)</font>"
var strCLodopUpdate =
"<br><font color='#FF00FF'>CLodop云打印服务需升级!点击这里<a href='http://www.c-lodop.com/download/CLodop_Setup_for_Win32NT_https_3.008Extend.zip' target='_self'>执行升级</a>,升级后请刷新页面。</font>"
var LODOP
try {
var isIE =
navigator.userAgent.indexOf('MSIE') >= 0 ||
navigator.userAgent.indexOf('Trident') >= 0
if (needCLodop()) {
try {
LODOP = getCLodop()
} catch (err) {}
if (!LODOP && document.readyState !== 'complete') {
alert('C-Lodop没准备好,请稍后再试!')
return
}
if (!LODOP) {
// if (isIE) document.write(strCLodopInstall); else
// document.documentElement.innerHTML=strCLodopInstall+document.documentElement.innerHTML;
// return;
if (isIE) document.write(strHtmInstall)
else {
document.documentElement.innerHTML =
strHtmInstall + document.documentElement.innerHTML
}
return LODOP
} else {
if (CLODOP.CVERSION < '3.0.0.2') {
if (isIE) document.write(strCLodopUpdate)
else {
document.documentElement.innerHTML =
strCLodopUpdate + document.documentElement.innerHTML
}
}
if (oEMBED && oEMBED.parentNode) oEMBED.parentNode.removeChild(oEMBED)
if (oOBJECT && oOBJECT.parentNode)
oOBJECT.parentNode.removeChild(oOBJECT)
}
} else {
var is64IE = isIE && navigator.userAgent.indexOf('x64') >= 0
//= ====如果页面有Lodop就直接使用,没有则新建:==========
if (oOBJECT != undefined || oEMBED != undefined) {
if (isIE) LODOP = oOBJECT
else LODOP = oEMBED
} else if (CreatedOKLodop7766 == null) {
LODOP = document.createElement('object')
LODOP.setAttribute('width', 0)
LODOP.setAttribute('height', 0)
LODOP.setAttribute(
'style',
'position:absolute;left:0px;top:-100px;width:0px;height:0px;'
)
if (isIE)
LODOP.setAttribute(
'classid',
'clsid:2105C259-1E0C-4534-8141-A753534CB4CA'
)
else LODOP.setAttribute('type', 'application/x-print-lodop')
document.documentElement.appendChild(LODOP)
CreatedOKLodop7766 = LODOP
} else LODOP = CreatedOKLodop7766
//= ====Lodop插件未安装时提示下载地址:==========
if (LODOP == null || typeof LODOP.VERSION == 'undefined') {
if (navigator.userAgent.indexOf('Chrome') >= 0) {
document.documentElement.innerHTML =
strHtmChrome + document.documentElement.innerHTML
}
if (navigator.userAgent.indexOf('Firefox') >= 0) {
document.documentElement.innerHTML =
strHtmFireFox + document.documentElement.innerHTML
}
if (is64IE) document.write(strHtm64_Install)
else if (isIE) document.write(strHtmInstall)
else {
document.documentElement.innerHTML =
strHtmInstall + document.documentElement.innerHTML
}
return LODOP
}
}
if (LODOP.VERSION < '6.0') {
if (!needCLodop()) {
if (is64IE) document.write(strHtm64_Update)
else if (isIE) document.write(strHtmUpdate)
else {
document.documentElement.innerHTML =
strHtmUpdate + document.documentElement.innerHTML
}
}
return LODOP
}
//= ==如下空白位置适合调用统一功能(如注册语句、语言选择等):===
// LODOP.SET_LICENSES("北京XXXXX公司","8xxxxxxxxxxxxx5","","");
//= ==========================================================
return LODOP
} catch (err) {
alert('getLodop出错:' + err)
}
}
2-3、引入后写打印方法
import { getLodop } from '@/assets/js/lodop.js' //这是引入,文件名字自己改的
//打印新增信息
printMeAuto() { //这个是打印代码
var self = this
let LODOP = getLodop() //主要代码
LODOP.PRINT_INIT()
LODOP.SET_PRINT_PAGESIZE(3, 580, 200)
LODOP.ADD_PRINT_HTM(
0,
0,
'100%',
'100%',
document.getElementById('printMeauto').innerHTML //获取要打印部分html
)
//以上为声明打印参数,具体请参照官网示例
//以下是成功加入打印队列之后的回调,如果不用刻意不看,直接执行LODOP.PRINT()
LODOP.SET_PRINT_MODE('CATCH_PRINT_STATUS', true)
if (LODOP.CVERSION) {
//判断c_lodop是否存在,安装了c-lodop就会存在
LODOP.On_Return = function(TaskID, Value) {
// console.log('TaskID:' + TaskID)
console.log('Value:' + Value) //job代码
self.jobCode = Value
if (!!Value) {
//如果成功,改变打印次数
ChangePrintCount(self.newDataAuto).then((res) => {
if (res.status !== 1) {
self.$notify.error({
title: '错误',
message: res.message,
})
}
})
return
}
}
LODOP.PRINT() //这是执行打印(无预览)
// LODOP.PREVIEW() 这是有预览打印
self.dialogVisible = false
return
} else {
console.log('c-lodop出错了')
}
},
附:官网示例地址:官网示例地址
3、实现与后台实时连接
这里我们可能首先想到的是与后台建立长连接,或者进行轮询,其实这也都是这么做的,方法也有很多种,在本次项目中,与后端商量后使用了signalr来进行前后的通讯
3-1、插件安装
npm i @aspnet/signalr
本来是直接使用signalr官方的插件的,但是因为jquery在vue cli里面引入全局后signalr总是找不到jquery,即使引入在他前面也不行,改了源码之后又找不到其中一个方法,最后逼不得已换插件。
3-2、编写监听和推送方法
import { HubConnectionBuilder, LogLevel } from '@aspnet/signalr' //引入signalr
import store from '@/store/index' //引入vuex,便于数据公用
export default {
install(Vue) {
// 使用新的Vue实例作为Vue组件接收/发送信号器事件的接口
// 这样,每个组件都可以使用此工具监听事件或发送新事件。$questionHub
const questionHub = new Vue()
Vue.prototype.$questionHub = questionHub
// 提供连接/断开信号器集线器的方法
let connection = null
let startedPromise = null
let manuallyClosed = false
Vue.prototype.startSignalR = (jwtToken) => {
connection = new HubConnectionBuilder()
.withUrl( //更换地点一,地址拼接,这个请找后台要方法,或者你说后台改
`${store.state.urlAuto}/apphub`,
jwtToken ? { accessTokenFactory: () => jwtToken } : null
)
.configureLogging(LogLevel.Information)
.build()
//更换地点二,这是后台调用前台JS方法的注册,QuestionAddedPrint为调用方法,
//自行更换,recoredId是返回值
// orward hub事件,这样我们就可以在Vue组件中监听它们
connection.on('QuestionAddedPrint', (recoredId) => {
questionHub.$emit('question-added-print', recoredId)
})
// 你需要打电话连接.启动()以建立连接,但客户端不会为您处理重新连接!
//医生建议在关闭时监听并在那里处理
// This is the simplest of the strategies
function start() {
startedPromise = connection.start().catch((err) => {
console.error('Failed to connect with hub', err)
return new Promise((resolve, reject) =>
setTimeout(
() =>
start()
.then(resolve)
.catch(reject),
5000
)
)
})
return startedPromise
}
connection.onclose(() => {
if (!manuallyClosed) start()
})
// Start everything
manuallyClosed = false
start()
}
//绑定启动命令
Vue.prototype.stopSignalR = () => {
if (!startedPromise) return
manuallyClosed = true
return startedPromise
.then(() => connection.stop())
.then(() => {
startedPromise = null
})
}
// Provide methods for components to send messages back to server
// Make sure no invocation happens until the connection is established
//这里是前台调用后台方法SetCurrentClientHub,这个可自行书写
questionHub.setCurrentClientHub = () => {
if (!startedPromise) return
return startedPromise
.then(() => connection.invoke('SetCurrentClientHub'))
.catch(console.error)
}
},
}
我的做法是把所有方法绑在了vue的原型上,看着不舒服的请自行更改
3-3、在项目(main.js)中引入
import QuestionHub from './question-hub' //question-hub是文件名,自己改就好
Vue.use(QuestionHub)
3-4、在需要的页面(可全局监听,看自己)使用
created() {
this.startSignalR() //启动SignalR开启链接,我绑在了原型上,所以直接this.就行,如果是其他绑定,请更换
this.$questionHub.setCurrentClientHub() //这个方法没啥大用,就是调用后台的一个方法,告诉他我连上了,可以不要
this.$questionHub.$on('question-added-print', this.print) //监听后台方法,后台一旦调用,前台就调用this.print方法
},
print(recoredId) { //其中的recoredId是写在上面文件中的后台的返回值
this.viewDetailAuto('', recoredId) //这个是调用接口方法,根据ID来查询要打印页面的数据,可以直接跳过
},
//在这个方法里面就可以直接调用之前写到的打印的方法了,到这里就已经实现了,后台数据一改变就自动打印的操作
本次的分享到这里就结束了,代码上来说,大多数都是可以直接复制粘贴直接用,需要更改的地方我也都有标注,看起来其实还是略显麻烦,如果谁有更好的方法,麻烦请留言告知,感激不尽。
更多推荐
所有评论(0)