Vue3造轮子之Typescript配置highlight过程
作者:存梨
这篇文章主要介绍了Vue3造轮子之Typescript配置highlight过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
项目基础是 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>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。