Plus 组件

代码高亮

根据语法高亮页面中的代码块

使用场景

Semi 代码高亮组件基于 Shiki 封装,使用与 VS Code 相同的 TextMate 语法。要高亮的语言由使用方注册,产物中只包含注册过的语法;未注册的语言按纯文本显示。高亮配色默认使用 Shiki 内置的 github-light 与 github-dark 主题,并随 Semi 的亮色、暗色模式自动切换,也可以换成其他主题。
需要展示代码片段时推荐使用 CodeHighlight 组件

代码演示

如何引入

<script setup lang="ts">
    import { CodeHighlight } from '@fibrous/semi-ui-vue';
</script>

注册语言与主题

语法与主题文件来自 shiki 包,使用前先在项目中安装 shiki。在应用入口调用一次 CodeHighlight.register,注册之后所有 CodeHighlight 都能使用这些语言。

语言以 () => import(...) 的形式传入时,语法文件在首次高亮任一代码块时加载,且会加载全部已注册的语言,而不只是该代码块用到的那一种。可用的语言及其名称、别名见 Shiki 语言列表,主题见 Shiki 主题列表。注册晚于代码块挂载时,已挂载的代码块会重新高亮

import { CodeHighlight } from '@fibrous/semi-ui-vue';

CodeHighlight.register({
    languages: [() => import('shiki/langs/javascript.mjs'), () => import('shiki/langs/css.mjs')],
    // 可选,替换默认的 github-light 与 github-dark
    themes: { light: () => import('shiki/themes/min-light.mjs'), dark: () => import('shiki/themes/nord.mjs') },
});

基本用法

向 code props 传入代码纯文本,并在 language 传入已注册语言的名称或别名


import * as React from 'react'
const Test = ()=>{
    const handleClick = ()=>{
        alert("Click")
    }
    return <div onClick={handleClick}>test</div>
}
代码
<script setup lang="ts">
    import { CodeHighlight } from '@fibrous/semi-ui-vue';

    const code = `
import * as React from 'react'
const Test = ()=>{
    const handleClick = ()=>{
        alert("Click")
    }
    return <div onClick={handleClick}>test</div>
}`;
</script>

<template>
    <CodeHighlight :code="code" language="javascript" />
</template>

CSS

.grid {
    .semi-row,
    .semi-row-flex {
        text-align: center;
        .semi-col {
            min-height: 30px;
            line-height: 30px;
            background: var(--semi-color-primary-light-default);
            outline: 1px solid var(--semi-color-primary-light-active);
        }
    }
}
代码
<script setup lang="ts">
    import { CodeHighlight } from '@fibrous/semi-ui-vue';

    const code = `.grid {
    .semi-row,
    .semi-row-flex {
        text-align: center;
        .semi-col {
            min-height: 30px;
            line-height: 30px;
            background: var(--semi-color-primary-light-default);
            outline: 1px solid var(--semi-color-primary-light-active);
        }
    }
}
`;
</script>

<template>
    <CodeHighlight :code="code" language="css" />
</template>

单个代码块使用的语言

只有个别代码块用到的语言,可以通过 languages 传给该代码块,不必全局注册;themes 同样可以只替换该代码块的主题。这两个值请写在组件外部,避免每次渲染都换成新的数组或对象而重新高亮。例如高亮用于编写 GTK 程序前端 UI 的 Vala 语言

public class ExampleApp : Gtk.Application {
    public ExampleApp () {
        Object (application_id: "com.example.App");
    }

    public override void activate () {
        var win = new Gtk.ApplicationWindow (this);

        var btn = new Gtk.Button.with_label ("Hello World");
        btn.clicked.connect (win.close);

        win.child = btn;
        win.present ();
    }

    public static int main (string[] args) {
        var app = new ExampleApp ();
        return app.run (args);
    }
}
代码
<script setup lang="ts">
    import { CodeHighlight } from '@fibrous/semi-ui-vue';

    // declared at the top level so the array is not new on every render, which would highlight again
    const languages = [() => import('shiki/langs/vala.mjs')];

    const code = `public class ExampleApp : Gtk.Application {
    public ExampleApp () {
        Object (application_id: "com.example.App");
    }

    public override void activate () {
        var win = new Gtk.ApplicationWindow (this);

        var btn = new Gtk.Button.with_label ("Hello World");
        btn.clicked.connect (win.close);

        win.child = btn;
        win.present ();
    }

    public static int main (string[] args) {
        var app = new ExampleApp ();
        return app.run (args);
    }
}
`;
</script>

<template>
    <CodeHighlight :code="code" language="vala" :languages="languages" />
</template>

API

Props

属性说明类型默认值
code代码纯文本,未传时按空字符串处理。code 变化后先显示新文本,高亮完成后再替换。stringsemiGlobalDefault("CodeHighlight", "code")
language语言类型,需已注册或经 languages 传入。stringundefined
lineNumber是否开启行数显示。booleansemiDefault("CodeHighlight", "lineNumber", true)
languages该代码块额外使用的 Shiki 语法,加载后其他代码块也可使用。请在 script setup 顶层声明,不要在模板里写内联数组,否则每次渲染都会重新高亮。LanguageInput[]semiGlobalDefault("CodeHighlight", "languages")
themes替换该代码块亮色、暗色模式下的 Shiki 主题。CodeHighlightThemessemiGlobalDefault("CodeHighlight", "themes")

Events

事件说明回调参数
无

Slots

插槽说明作用域参数
无

Exposes

名称说明类型
无

class、style 与原生属性经 attrs 落在根元素上。高亮完成前后根元素会被替换($el 不稳定),这些属性每次都会重新应用到新的根元素上。languages、themes 传入 ref 或 reactive 的值也可以,组件传给 Shiki 的是原始对象。

静态方法

方法说明类型
CodeHighlight.register注册所有 CodeHighlight 可用的语言,并替换默认主题;可多次调用,语言累加、主题覆盖(options: { languages?: LanguageInput[]; themes?: { light?: ThemeInput; dark?: ThemeInput } }) => void

Accessibility

  • 根元素传入 aria-label 或 aria-labelledby 且未传 role 时,自动带 role="group"(通用元素不能被命名);传入的 role 优先

设计变量