feat: 代码高亮和复制

This commit is contained in:
bunny 2025-04-20 23:04:09 +08:00
parent 72f39513ca
commit 4ee723cce1
7 changed files with 87 additions and 9 deletions

View File

@ -13,11 +13,13 @@
},
"dependencies": {
"@eslint/js": "^9.21.0",
"@highlightjs/vue-plugin": "^2.1.0",
"@types/node": "^22.13.10",
"@typescript-eslint/eslint-plugin": "^8.24.1",
"@typescript-eslint/parser": "^8.24.1",
"@unocss/preset-icons": "^66.0.0",
"@unocss/reset": "^66.0.0",
"@vicons/ionicons5": "^0.13.0",
"@vitejs/plugin-vue-jsx": "^4.1.1",
"animate.css": "^4.1.1",
"axios": "^1.7.9",
@ -30,6 +32,7 @@
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-vue": "^9.27.0",
"gradient-string": "^3.0.0",
"highlight.js": "^11.11.1",
"naive-ui": "^2.41.0",
"nprogress": "^0.2.0",
"pinia": "^2.3.1",
@ -85,5 +88,6 @@
"eslint": "9"
}
}
}
},
"packageManager": "pnpm@10.8.1+sha512.c50088ba998c67b8ca8c99df8a5e02fd2ae2e2b29aaf238feaa9e124248d3f48f9fb6db2424949ff901cffbb5e0f0cc1ad6aedb602cd29450751d11c35023677"
}

View File

@ -11,6 +11,9 @@ importers:
'@eslint/js':
specifier: ^9.21.0
version: 9.21.0
'@highlightjs/vue-plugin':
specifier: ^2.1.0
version: 2.1.0(highlight.js@11.11.1)(vue@3.5.13(typescript@5.7.3))
'@types/node':
specifier: ^22.13.10
version: 22.13.10
@ -26,6 +29,9 @@ importers:
'@unocss/reset':
specifier: ^66.0.0
version: 66.0.0
'@vicons/ionicons5':
specifier: ^0.13.0
version: 0.13.0
'@vitejs/plugin-vue-jsx':
specifier: ^4.1.1
version: 4.1.1(vite@6.1.1(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(sass@1.85.0)(terser@5.39.0))(vue@3.5.13(typescript@5.7.3))
@ -62,6 +68,9 @@ importers:
gradient-string:
specifier: ^3.0.0
version: 3.0.0
highlight.js:
specifier: ^11.11.1
version: 11.11.1
naive-ui:
specifier: ^2.41.0
version: 2.41.0(vue@3.5.13(typescript@5.7.3))
@ -690,6 +699,12 @@ packages:
resolution: {integrity: sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@highlightjs/vue-plugin@2.1.0':
resolution: {integrity: sha512-E+bmk4ncca+hBEYRV2a+1aIzIV0VSY/e5ArjpuSN9IO7wBJrzUE2u4ESCwrbQD7sAy+jWQjkV5qCCWgc+pu7CQ==}
peerDependencies:
highlight.js: ^11.0.1
vue: ^3
'@humanfs/core@0.19.1':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
engines: {node: '>=18.18.0'}
@ -1132,6 +1147,9 @@ packages:
peerDependencies:
vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0
'@vicons/ionicons5@0.13.0':
resolution: {integrity: sha512-zvZKBPjEXKN7AXNo2Na2uy+nvuv6SP4KAMQxpKL2vfHMj0fSvuw7JZcOPCjQC3e7ayssKnaoFVAhbYcW6v41qQ==}
'@vitejs/plugin-vue-jsx@4.1.1':
resolution: {integrity: sha512-uMJqv/7u1zz/9NbWAD3XdjaY20tKTf17XVfQ9zq4wY1BjsB/PjpJPMe2xiG39QpP4ZdhYNhm4Hvo66uJrykNLA==}
engines: {node: ^18.0.0 || >=20.0.0}
@ -3316,6 +3334,11 @@ snapshots:
'@eslint/core': 0.12.0
levn: 0.4.1
'@highlightjs/vue-plugin@2.1.0(highlight.js@11.11.1)(vue@3.5.13(typescript@5.7.3))':
dependencies:
highlight.js: 11.11.1
vue: 3.5.13(typescript@5.7.3)
'@humanfs/core@0.19.1': {}
'@humanfs/node@0.16.6':
@ -3775,6 +3798,8 @@ snapshots:
transitivePeerDependencies:
- vue
'@vicons/ionicons5@0.13.0': {}
'@vitejs/plugin-vue-jsx@4.1.1(vite@6.1.1(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.2)(sass@1.85.0)(terser@5.39.0))(vue@3.5.13(typescript@5.7.3))':
dependencies:
'@babel/core': 7.26.9

9
src/plugins/highLight.ts Normal file
View File

@ -0,0 +1,9 @@
import 'highlight.js/styles/atom-one-dark.css';
import 'highlight.js/lib/common';
import highlightJSPlugin from '@highlightjs/vue-plugin';
import type { App } from 'vue';
export const setupHighLight = (app: App<Element>) => {
app.use(highlightJSPlugin);
};

View File

@ -1,5 +1,6 @@
import type { App } from 'vue';
import { setupHighLight } from '@/plugins/highLight';
import { setupRouter } from '@/router';
import { setupStore } from '@/store';
@ -9,5 +10,7 @@ export default {
setupRouter(app);
// 设置状态管理
setupStore(app);
// 设置代码高亮
setupHighLight(app);
},
};

24
src/utils/copy.ts Normal file
View File

@ -0,0 +1,24 @@
/**
*
* @param text
*/
export const copy = (text: string) => {
const textarea = document.createElement('textarea');
textarea.value = text;
textarea.style.position = 'fixed';
document.body.appendChild(textarea);
textarea.select();
try {
const success = document.execCommand('copy');
if (success) {
(window as any as any).$message.success('复制成功!');
} else {
(window as any).$message.success('复制失败!');
}
} catch (err: any) {
(window as any).$message.success('复制失败!请手动复制');
} finally {
document.body.removeChild(textarea);
}
};

View File

@ -1,14 +1,21 @@
<script lang="tsx" setup>
import { NButton, NCollapse, NCollapseItem, NInput, useDialog, useMessage } from 'naive-ui';
import hljsVuePlugin from '@highlightjs/vue-plugin';
import { CopySharp } from '@vicons/ionicons5';
import { NButton, NCollapse, NCollapseItem, NIcon, NInput, useDialog, useMessage } from 'naive-ui';
import { ref } from 'vue';
import { useVmsStore } from '@/store/modules/vms';
import { copy } from '@/utils/copy';
import { downloadTextAsFile } from '@/utils/file';
// 使
const HighlightJS = hljsVuePlugin.component;
const dialog = useDialog();
const message = useMessage();
const vmsStore = useVmsStore();
/* 下载文件 */
const download = (code: string, filename: string) => {
const filenameSplit = filename.split('/');
@ -39,22 +46,27 @@ const download = (code: string, filename: string) => {
</script>
<template>
<n-collapse class="mt-4 p-2 border">
<n-collapse v-show="vmsStore.generators.length > 0" class="mt-4 p-2 border">
<n-collapse-item
v-for="(item, index) in vmsStore.generators"
:key="index"
:name="item.path"
:title="item.path"
class="pos-relative"
>
<template #header-extra>
<n-button quaternary type="info" @click="download(item.code, item.path)">下载</n-button>
</template>
<n-input
:autosize="{ minRows: 3 }"
:placeholder="item.comment"
:value="item.code"
type="textarea"
/>
<n-button class="pos-absolute right-0" color="#ff69b4" quaternary @click="copy(item.code)">
<template #icon>
<n-icon>
<CopySharp />
</n-icon>
</template>
复制
</n-button>
<HighlightJS :autodetect="true" :code="item.code" language="JavaScript" />
</n-collapse-item>
</n-collapse>
</template>

View File

@ -4,6 +4,7 @@ import GeneratorPreview from '@/views/generator-code/generator/components/genera
</script>
<template>
<!-- 生成要提交的表单 -->
<generator-form />
<!-- 生成好的数据 -->