今天小编在教课的时候,发现很多刚刚接触这个领域的同学对一些小的细节部分还是存在疑惑,网上的很多博客也只是只贴出了代码,并不了解是什么意思,小编今天就具体的来给讲一讲如何在vue-cli的环境下实现web的打印指定区域的内容(文字或者表格图表),让大家在学习的过程中少走一些弯路。
走起,先看效果图:
![1f3647f123996b9840b10e4e01377de5.png](https://i-blog.csdnimg.cn/blog_migrate/4b38fb31d0c58c43ad140462024027a4.jpeg)
如何实现上诉需求呢,咱们来一一讲解,首先咱们先把代码切分为四个部分:
1.创建一个构造函数Print
2.给Print的prototype添加需要用到方法
3.声明一个常量MyPlugin 为它添加方法 将Print方法挂载到Vue原型链上
4.export导出MyPlugin
![391b2402af84f69fa516e39046c9beb8.png](https://i-blog.csdnimg.cn/blog_migrate/a60f9221b759fe462baa40cfecd81896.jpeg)
![4914b0ac2e4b3011bed9c97959eeebc0.png](https://i-blog.csdnimg.cn/blog_migrate/6f1b3ac1e442e0056de350f2091e98b7.jpeg)
第一步创建一个构造函数Print 默认接受两个参数 一个是打印的指定区,一个是自定义页眉的标题。
要注意哦,有些同学这里可能会不懂这个判断的意思,因为这里的this是指向Vue的 通过instanceof 来判断这时候的this是否为Print的子类 如果不是 就通过new操作符调用 使this 指向Print本身。
然后这里做一个容错,判断一下传进来的dom是否为object、是否有nodeType和nodeName这两个属性,如果没有,证明不是一个节点 那就取dom下的$el,然后把处理过后的dom和name分别赋值给this.dom和this.name,方便在prototype里随时取值,同时执行初始化方法。
![b846d21aadef49881faa210e1e60ca2b.png](https://i-blog.csdnimg.cn/blog_migrate/05e36c761fb0d63c9f56dda47a9bb6d0.jpeg)
init方法里为了实现打印 并且自定义标题 我们需要重新获取到样式和页面元素 展示到一个新的html里面,最后通过writeIframe方法完成咱们最终打印的效果。
在getStyle方法里 自定义一个空字符串 通过 querySelectorAll 方法获取到当前页面全部的style和link标签,并且通过循环拿到每一个的outerHTML(纯文本形式)最后通过return暴露出来
![82b54417c3d40ae4eba748d52dd22063.png](https://i-blog.csdnimg.cn/blog_migrate/b4daf8734f1f968acfc0df99d093c24b.jpeg)
getHtml方法主要是特殊处理一下 input、textarea、select、canvas 把前三个打value值重新获取通过innerHTML的方法展现出来,把canvas画布转换成图片的格式展现出来。然后进入下一步setHeader方法,来自定义页眉的标题。
这里是因为在DOM上,input、textarea、select中的值并没有在元素内,只有纯文本才可以被print(),同样打印也不支持canvas。所以咱们需要重新处理一下,使里面的值也可以被打印出来~
![6abc017cb95cd264685fba47b8b39bf2.png](https://i-blog.csdnimg.cn/blog_migrate/8b0a87454d3a8466ad29ddeb2cb244db.jpeg)
在这一步,咱们实际上是重新创建了一个html标签和title,然后通过克隆出要打印的区域,添加到新创建的html当中。
然后return出这个新页面里的全部纯文本元素。这个时候已经咱们需要打印的html和自定义标题已经出来了。
这里同学们千万要注意,因为打印的默认标题是页面里的title,如果直接改变原页面的title来实现自定义标题效果的话,会造成原页面的title错乱。
![3b6578eb843414bec5862095babed8df.png](https://i-blog.csdnimg.cn/blog_migrate/a3c3f22f97ee131a1e2d66a9a3e1f6a9.jpeg)
这个时候回到init方法 content就是咱们全部需要输入的标签。执行writeIframe方法,这里面主要是通过document.open 来打开一个新文档,document.write来编写文档的内容,document.close 来关闭文档操作 使其内容可以显示出来
然后红线圈出的地方有一个获取全部类名为isNeedRemove的操作,是因为之前在把canvas转换成图片的时候 给每个的后面都插入了一个转换后的img 这里为了让图形不出现两个的情况 需要删除所有类名为isNeedRemove的节点,同时执行最终的打印方法。
![f137da7b84cc0af5c9698edb5678dd44.png](https://i-blog.csdnimg.cn/blog_migrate/5c86ba2d4df40646b5b6399f4ded5225.jpeg)
这里的frameWindow形参其实就是咱们需要调用到的window,通过try catch来保证结果在一个控制范围内 如果成功运行 调用window下的print方法 失败则抛出异常。
![495b2ccf18394f1bc2bd34c0a1fd6a6b.png](https://i-blog.csdnimg.cn/blog_migrate/68dc5108ec90a6bafdfb80cf30f86d69.jpeg)
最终将写好的方法添加到vue的原型链上,在公共的main.js 里通过import 引入,Vue.use挂载,然后在想要使用的组件内直接通过this.$print()使用即可
好啦~今天讲到这里希望大家对这个web前端来实现打印的方法有一个新的理解,希望能给到大家一些帮助~咱们下期再见。