Highlight 代码高亮
简介
把 Prism 封装成组件,内置复制按钮。支持 20 多种语言的语法着色、超长代码内部滚动,也可以把代码放进默认插槽。代码区字号固定 13px,不随外层字号变化。
代码演示
基础使用
code 设置代码内容,lang 设置语言,不传时按纯文本渲染。右上角是复制按钮,复制到的是原始代码。
vue
<template>
<co-highlight :code="code" lang="json" />
</template>
<script lang="ts" setup>
const code = `{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.formatOnSaveMode": "file",
"typescript.tsdk": "node_modules/typescript/lib",
"files.associations": {
"*.css": "tailwindcss"
},
"npm.packageManager": "pnpm",
"[xml]": {
"editor.defaultFormatter": "redhat.vscode-xml"
}
}`;
</script>
切换语言
lang 决定用哪套语法规则着色:ts / js / tsx / jsx、css / scss / less、html / xml / svg、json / json5、bash / shell、sql、python、java、php、nginx、markdown,以及 text / plain 等纯文本别名。传其它 Prism 语言名也可以,未注册时自动退回纯文本。
vue
<template>
<div class="lang-demo">
<el-radio-group v-model="lang" size="small">
<el-radio-button value="ts">TypeScript</el-radio-button>
<el-radio-button value="css">CSS</el-radio-button>
<el-radio-button value="html">HTML</el-radio-button>
<el-radio-button value="sql">SQL</el-radio-button>
<el-radio-button value="bash">Bash</el-radio-button>
<el-radio-button value="text">纯文本</el-radio-button>
</el-radio-group>
<co-highlight :code="samples[lang]" :lang="lang" />
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
const lang = ref('ts');
const samples: Record<string, string> = {
ts: `interface Column {
key: string;
width?: number;
}
export function pick<T extends object, K extends keyof T>(
source: T,
keys: K[],
): Pick<T, K> {
return keys.reduce(
(acc, key) => ({ ...acc, [key]: source[key] }),
{} as Pick<T, K>,
);
}
const column: Column = { key: 'createdAt', width: 160 };`,
css: `.panel {
display: flex;
gap: 8px;
padding: 16px;
border-radius: 8px;
background: var(--el-bg-color);
}
.panel:hover {
border-color: var(--el-color-primary);
}`,
html: `<section class="panel" data-id="42">
<h2 class="panel__title">订单详情</h2>
<p class="panel__desc">下单后 24 小时内发货</p>
</section>`,
sql: `SELECT id, name, created_at
FROM users
WHERE status = 'active'
ORDER BY created_at DESC
LIMIT 20;`,
bash: `pnpm install
pnpm build --filter=docs
git commit -m "feat: 新增代码高亮示例"`,
text: `[2026-10-24 11:40:02] build started
[2026-10-24 11:40:18] build finished in 16.2s
[2026-10-24 11:40:18] 0 errors, 0 warnings`,
};
</script>
<style scoped>
.lang-demo {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 12px;
}
</style>
限制高度
max-height 传带单位的字符串,超出后代码区内部滚动,复制按钮固定在右上角不跟着滚。
vue
<template>
<div class="stack">
<p class="label">max-height="180px":超出后内部滚动,复制按钮固定在右上角</p>
<co-highlight :code="code" lang="ts" max-height="180px" />
</div>
</template>
<script lang="ts" setup>
const code = `export interface TableColumn {
key: string;
title: string;
width?: number;
minWidth?: number;
align?: 'left' | 'center' | 'right';
fixed?: 'left' | 'right';
sortable?: boolean;
ellipsis?: boolean;
}
export const columns: TableColumn[] = [
{ key: 'name', title: '名称', minWidth: 160 },
{ key: 'status', title: '状态', width: 96, align: 'center' },
{ key: 'owner', title: '负责人', width: 120 },
{ key: 'createdAt', title: '创建时间', width: 168, sortable: true },
{ key: 'updatedAt', title: '更新时间', width: 168, sortable: true },
{ key: 'remark', title: '备注', minWidth: 240, ellipsis: true },
];
export const defaultSort = {
field: 'createdAt',
order: 'desc' as const,
};`;
</script>
<style scoped>
.stack {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
}
.label {
margin: 0;
font-size: 12px;
color: var(--el-text-color-secondary);
}
</style>
通过插槽传入
不传 code 时,默认插槽里的纯文本会被当作代码;两者都给时以 code 为准。
vue
<template>
<div class="stack">
<p class="label">
不传 code,直接把代码放进默认插槽(同
<code>code</code>
,取纯文本)
</p>
<co-highlight lang="bash">{{ script }}</co-highlight>
</div>
</template>
<script lang="ts" setup>
const script = `#!/usr/bin/env bash
set -euo pipefail
VERSION=$(node -p "require('./package.json').version")
echo "building cosey@$VERSION"
pnpm build
git tag "v$VERSION"
git push origin "v$VERSION"`;
</script>
<style scoped>
.stack {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 8px;
}
.label {
margin: 0;
font-size: 12px;
color: var(--el-text-color-secondary);
}
</style>
API
HighlightProps
| 属性 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| code | 要高亮的代码内容 | string | - |
| lang | 代码语言,取值见上方「切换语言」 | string | 'text' |
| maxHeight | 代码区最大高度,超出滚动 | string | - |
HighlightSlots
| 插槽 | 描述 | 属性 |
|---|---|---|
| default | 代码内容(code 为空时生效) | - |