CodeBlock 代码块

成段的代码,带语法着色、语言角标与复制按钮。

import { createApp } from 'vue'
import App from './App.vue'
import '@hina-ui/vue/styles/tokens.css'

createApp(App).mount('#app')
ts
<script setup lang="ts">
  import { CodeBlock } from '@hina-ui/vue'

  const source = `import { createApp } from 'vue'
import App from './App.vue'
import '@hina-ui/vue/styles/tokens.css'

createApp(App).mount('#app')`
</script>

<template>
  <CodeBlock :code="source" lang="ts" class="w-full max-w-xl" />
</template>
vue

用法

import { CodeBlock } from '@hina-ui/vue'
ts

code 是必填属性,内容原样呈现。lang 指定语言,组件据此着色,并在右上角显示语言角标。

pnpm add @hina-ui/vue
bash
<script setup lang="ts">
  import { CodeBlock } from '@hina-ui/vue'
</script>

<template>
  <CodeBlock code="pnpm add @hina-ui/vue" lang="bash" class="w-full max-w-xl" />
</template>
vue

示例

角标文字

角标默认显示 lang。设置 label 可以改为文件名或其他说明,着色仍然依据 lang。

export default defineNuxtConfig({
  css: ['@hina-ui/vue/styles/tokens.css'],
})
nuxt.config.ts
<script setup lang="ts">
  import { CodeBlock } from '@hina-ui/vue'

  const source = `export default defineNuxtConfig({
  css: ['@hina-ui/vue/styles/tokens.css'],
})`
</script>

<template>
  <CodeBlock :code="source" lang="ts" label="nuxt.config.ts" class="w-full max-w-xl" />
</template>
vue

不着色

不指定 lang 时不着色,也不显示角标,代码按原样呈现。命令行输出与纯文本适合这样使用。

✔ 依赖安装完成
✔ 样式入口已就绪
  运行 pnpm dev 启动开发服务器
<script setup lang="ts">
  import { CodeBlock } from '@hina-ui/vue'

  const output = `✔ 依赖安装完成
✔ 样式入口已就绪
  运行 pnpm dev 启动开发服务器`
</script>

<template>
  <CodeBlock :code="output" class="w-full max-w-xl" />
</template>
vue

复制按钮

右上角默认带复制按钮。设置 copyable 为 false 可以移除它。

git switch -c feature/hina-ui
bash
<script setup lang="ts">
  import { CodeBlock } from '@hina-ui/vue'
</script>

<template>
  <CodeBlock
    code="git switch -c feature/hina-ui"
    lang="bash"
    :copyable="false"
    class="w-full max-w-xl"
  />
</template>
vue

超长的行

代码不换行。超出宽度时在代码块内横向滚动,页面本身不会被撑宽。滚动区可以聚焦,聚焦后能用方向键滚动。

const theme = { accent: 'var(--hn-accent)', radius: 'var(--hn-radius-lg)', shadow: 'var(--hn-shadow-sm)', font: 'var(--hn-font-sans)' }
ts
<script setup lang="ts">
  import { CodeBlock } from '@hina-ui/vue'

  const source = `const theme = { accent: 'var(--hn-accent)', radius: 'var(--hn-radius-lg)', shadow: 'var(--hn-shadow-sm)', font: 'var(--hn-font-sans)' }`
</script>

<template>
  <CodeBlock :code="source" lang="ts" class="w-full max-w-md" />
</template>
vue

高度

使用 class 或 style 设置 height,超出高度的代码在内部纵向滚动。长行仍可横向滚动,角标和复制按钮固定在右上角。

const value1 = { name: 'Hina UI', enabled: true }
const value2 = { name: 'Hina UI', enabled: true }
const value3 = { name: 'Hina UI', enabled: true }
const value4 = { name: 'Hina UI', enabled: true }
const value5 = { name: 'Hina UI', enabled: true }
const value6 = { name: 'Hina UI', enabled: true }
const value7 = { name: 'Hina UI', enabled: true }
const value8 = { name: 'Hina UI', enabled: true }
const value9 = { name: 'Hina UI', enabled: true }
const value10 = { name: 'Hina UI', enabled: true }
const value11 = { name: 'Hina UI', enabled: true }
const value12 = { name: 'Hina UI', enabled: true }
const value13 = { name: 'Hina UI', enabled: true }
const value14 = { name: 'Hina UI', enabled: true }
const value15 = { name: 'Hina UI', enabled: true }
const value16 = { name: 'Hina UI', enabled: true }
ts
<script setup lang="ts">
  import { CodeBlock } from '@hina-ui/vue'

  const source = Array.from(
    { length: 16 },
    (_, index) => 'const value' + (index + 1) + " = { name: 'Hina UI', enabled: true }",
  ).join('\n')
</script>

<template>
  <CodeBlock :code="source" lang="ts" class="h-48 w-full max-w-lg" />
</template>
vue

设置 max-height 可以限制最大高度。内容较少时保持自然高度,超出上限后才出现纵向滚动。

const value1 = { name: 'Hina UI', enabled: true }
const value2 = { name: 'Hina UI', enabled: true }
const value3 = { name: 'Hina UI', enabled: true }
const value4 = { name: 'Hina UI', enabled: true }
const value5 = { name: 'Hina UI', enabled: true }
const value6 = { name: 'Hina UI', enabled: true }
const value7 = { name: 'Hina UI', enabled: true }
const value8 = { name: 'Hina UI', enabled: true }
const value9 = { name: 'Hina UI', enabled: true }
const value10 = { name: 'Hina UI', enabled: true }
const value11 = { name: 'Hina UI', enabled: true }
const value12 = { name: 'Hina UI', enabled: true }
const value13 = { name: 'Hina UI', enabled: true }
const value14 = { name: 'Hina UI', enabled: true }
const value15 = { name: 'Hina UI', enabled: true }
const value16 = { name: 'Hina UI', enabled: true }
ts
<script setup lang="ts">
  import { CodeBlock } from '@hina-ui/vue'

  const source = Array.from(
    { length: 16 },
    (_, index) => 'const value' + (index + 1) + " = { name: 'Hina UI', enabled: true }",
  ).join('\n')
</script>

<template>
  <CodeBlock :code="source" lang="ts" class="max-h-48 w-full max-w-lg" />
</template>
vue

预先着色

html 属性接受已经着色好的 HTML。传入之后组件不再运行着色,直接呈现该内容,code 仍用于复制。

在服务端或者构建时完成着色,可以让浏览器不必下载着色器。

const accent = '#39c5bb'
ts
<script setup lang="ts">
  import { CodeBlock } from '@hina-ui/vue'

  const code = `const accent = '#39c5bb'`
  const html = `<span style="color:#8250df">const</span><span> accent = </span><span style="color:#0a3069">'#39c5bb'</span>`
</script>

<template>
  <CodeBlock :code="code" :html="html" lang="ts" class="w-full max-w-xl" />
</template>
vue

无障碍

  • 滚动区可以聚焦,聚焦后用方向键滚动,焦点框出现在代码块外沿。
  • 滚动区的无障碍名称取自角标,未设置角标时为通用名称。
  • 复制按钮的名称为“复制代码”,复制成功后变为“已复制”。

API

Props

属性
类型
默认值
说明
code
string
—
必填。代码文本,同时用于复制
lang
string
—
语言,决定着色与角标
label
string
—
角标文字,覆盖 lang
html
string
—
预先着色好的 HTML,传入后不再着色
copyable
boolean
true
是否显示复制按钮
class
string
—
追加至根元素的类名