[Js]使用highlight.js高亮vue代码
Vue SFC (.vue) 文件本身是 复合语言,包含 <template>
、<script>
、<style>
。
所以只使用单语言进行高亮效果很差。
思路是通过工具进行拆分,单部分进行高亮,再通过拆分参数进行整合
- 高亮使用
highlight.js
- 拆分使用
@vue/compiler-sfc
目前粗略的试了下,是可以实现的
示例代码
其中vue3_ts_prefix
等几个变量是我提前格式化一遍的,后续等做工具的时候,可以放到逻辑里实现
js
import hljs from 'highlight.js/lib/core'
import plaintext from 'highlight.js/lib/languages/plaintext'
import html from 'highlight.js/lib/languages/xml'
import js from 'highlight.js/lib/languages/javascript'
import ts from 'highlight.js/lib/languages/typescript'
import css from 'highlight.js/lib/languages/css'
import { parse } from '@vue/compiler-sfc'
// 注册语言
if (!hljs.getLanguage('plaintext')) hljs.registerLanguage('plaintext', plaintext)
if (!hljs.getLanguage('html')) hljs.registerLanguage('html', html)
if (!hljs.getLanguage('js')) hljs.registerLanguage('js', js)
if (!hljs.getLanguage('ts')) hljs.registerLanguage('ts', ts)
if (!hljs.getLanguage('css')) hljs.registerLanguage('css', css)
const TypeMap: Record<string, string> = {
html: 'html',
js: 'js',
css: 'css'
}
const vue3_ts_prefix =
'<span class="hljs-tag"><<span class="hljs-name">script</span> <span class="hljs-attr">setup</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"ts"</span>></span>'
const vue3_ts_suffix = '<span class="hljs-tag"></<span class="hljs-name">script</span>></span>'
const vue3_html_prefix = '<span class="hljs-tag"><<span class="hljs-name">template</span>></span>'
const vue3_html_suffix = '<span class="hljs-tag"></<span class="hljs-name">template</span>></span>'
export const renderCode = (code: string, type: string) => {
if (type === 'vue3') {
const { descriptor } = parse(code)
let text = ''
if (descriptor.scriptSetup) {
const t1 = hljs.highlight(descriptor.scriptSetup.content, { language: 'ts' }).value
text += vue3_ts_prefix + t1 + vue3_ts_suffix
}
if (descriptor.template) {
const t2 = hljs.highlight(descriptor.template.content, { language: 'html' }).value
if (text) text += '\n\n'
text += vue3_html_prefix + t2 + vue3_html_suffix
}
return text
}
const language = TypeMap[type] || 'plaintext'
return hljs.highlight(code, { language }).value
}
使用效果
