技术博客里,最常见的就是代码了,没有语法高亮的代码,简直没法看下去。
常用的语法高亮 JS 库有 Highlight.js,Prism,SyntaxHighlighter 等等,它们的主要工作原理就是搜索 document
中的 <pre><code>
标签,再对其中内容进行正则匹配,识别出使用的语言并为某些内容添加 class
,最后根据 CSS
渲染样式。
问题
最近在写一个博客应用(开发中),语法高亮交给前端完成,这里我选择了 Highlight.js
作为语法高亮插件。
因为做的是单页应用,前端框架使用的是 Vue
,用 Webpack
作为脚手架,所以很自然地 npm i -S highlight.js
安装,之后把 hljs.initHighlightingOnLoad();
添加到代码里…
欸?为什么明明 hljs
已经注册为全局变量了,但是高亮不工作?是不是我的姿势不对?
解决
搜索了很多文章,之后发现是 Vue-Router
的锅,在 $route
改变进行跳转时,vue
会重新渲染页面,并移除页面上所有事件。所以在渲染页面后,监听已经被移除了,也就不会再进行语法高亮了。
有两种解决方案:
Vue
自定义指令:
使用 Vue
的自定义指令,可以在内容渲染时才搜索对应内容中的 <pre><code>
标签,控制更方便。
import hljs from 'highlight.js'; Vue.directive('hljs', el => { let blocks = el.querySelectorAll('pre code'); Array.prototype.forEach.call(blocks, hljs.highlightBlock); });
使用方法也很简单,在需要进行代码高亮的地方,加上 v-hljs
即可:
<div class="post-content" v-html="postData.content" v-hljs></div>
渲染后重新监听:
this.getReady(); // Ready hljs.initHighlightingOnLoad();
这要根据实际使用情况修改代码,没有第一种方法简单。这里就是在 Ajax
获取数据成功后,重新监听。
FAQ:
Q:为什么明明转换成功了,但是就是不见高亮?
A:Highlight.js
的使用说明比较简陋,不仔细看根本不知道样式文件在 highlight.js/src/styles
文件夹中,并需要自己手动引入。
Q:我明明使用的是 railscasts
的黑底样式,为什么总有一个 github
的白底样式,是不是会自动引入样式的,要怎么配置呢?
A:Highlight.js
不会自动引入样式,也无法配置。遇到这个问题可能是因为 PHP 的 DebugBar
会内置 github
样式,而且会覆盖手动引入的样式,需要关掉 DebugBar
或修改样式文件提高优先级。
参考:
http://www.ahonn.me/2016/07/13/getting-highlightjs-to-work-with-vue.js/
原创文章,转载请以链接形式注明出处:https://blog.ttionya.com/article-1649.html