项目基础是 vue3+typescript
实现一个简单的 UI 组件库。
在编写组件介绍文档时,需要提供一些代码示例,这时候用到了 hightlight.js
来实现代码的高亮。
一、安装 highlight.js
执行命令行进行依赖以及类型声明的安装
yarn add highlight.js @types/highlight.js
安装完成后,按照官方地址配置发现是无法使用的,报错情况如下
这个问题说明我们引入的类并没有 vuePlugin
这个属性
二、增加 highlight.ts 文件
那么我们基于 typescript 来使用 highlight.js
的话,就需要解决这个 vue.use()
的问题。
查阅资料得知,需要增加一个定义 vue 外部插件的 highlight.ts
如下所示,可放心复制
import Hljs from 'highlight.js';
import 'highlight.js/styles/monokai-sublime.css'
// 自定义的interface会导致报错
// interface Highlightjs {
// [x:string]:any
// }
//let Highlight:Highlightjs = {};
let Highlight:any = {};
Highlight.install = function (Vue:any,options:any) {
Vue.directive('highlightA',{
inserted:function(el:any){
let blocks = el.querySelectorAll('per code');
for (let i = 0; i < blocks.length; i++) {
const item = blocks[i]
Hljs.highlightBlock(item)
}
}
})
Vue.directive('highlightB',{
componentUpdated:function(el:any){
let blocks = el.querySelectorAll('per code');
for (let i = 0; i < blocks.length; i++) {
const item = blocks[i]
Hljs.highlightBlock(item)
}
}
})
}
export default Highlight
在这里曾尝试定义一个 Highlightjs
的接口类型,但是会导致报如下的错误,而放弃
初步分析该报错的原因是 interface
里的类型定义还是存在一定的问题,所以用了 any 类型暴力解决了。
三、在入口文件引入
定义好 highlight.ts
文件后,在我们的入口文件 main.ts
中引入即可
下面的代码可放心复制
import { createApp } from 'vue'
import router from './router'
import App from './App.vue'
import Highlight from './libs/types/highlight' // 路径对应你创建的highlight.ts的路径
const app = createApp(App)
app.use(router)
app.use(Highlight)
app.mount('#app')
到此,我们就可以在 ts 文件中正常的引入 hightlight.js
并开始使用了。
个人测试验证第二、第三步不可行,以下是更正后的方法
四、在入口文件注册指令
安装好 highlight.js
之后,我们在入口文件注册 vue 的自定义指令 directive
代码如下
import { createApp } from 'vue'
import router from './router'
import App from './App.vue'
import hljs from 'highlight.js'
import 'highlight.js/styles/monokai-sublime.css'
const app = createApp(App)
app.use(router)
// 注册自定义指令高亮代码
app.directive('highlight', {
// Directive has a set of lifecycle hooks:
// called before bound element's parent component is mounted
beforeMount(el:any) {
// on first bind, highlight all targets
let blocks = el.querySelectorAll('pre code');
for(let i = 0 ;i < blocks.length ; i++){
let item = blocks[i]
console.log(item)
hljs.highlightBlock(item)
}
},
// called after the containing component's VNode and the VNodes of its children // have updated
updated(el:any, binding:any) {
// after an update, re-fill the content and then highlight
let targets = el.querySelectorAll('code');
for (let i = 0; i < targets.length; i += 1) {
let target = targets[i];
if (typeof binding.value === 'string') {
target.textContent = binding.value;
}
hljs.highlightBlock(target);
}
}
})
app.mount('#app')
这样我们在组件中可以通过指令进行代码高亮的编写了,示例如下
<pre v-highlight>
<code class="javascript">
let a = "hello world";
console.log(a)
</code>
</pre>
参考博客