feat(icons): 添加 Lucide 图标组件并集成到首页

添加 Lucide Vue 图标库依赖,创建 AppIcon 基础组件用于统一管理图标
移除 .npmrc 文件并更新 pre-commit 钩子使用 npm 替代 pnpm
This commit is contained in:
houakang
2026-04-10 15:19:12 +08:00
parent 2d1fe95be0
commit 0b11680aea
6 changed files with 99 additions and 53 deletions

View File

@@ -1 +1 @@
pnpm exec lint-staged npm exec lint-staged

10
package-lock.json generated
View File

@@ -14,6 +14,7 @@
"bonjour-service": "^1.3.0", "bonjour-service": "^1.3.0",
"electron-squirrel-startup": "^1.0.1", "electron-squirrel-startup": "^1.0.1",
"element-plus": "^2.13.6", "element-plus": "^2.13.6",
"lucide-vue-next": "^1.0.0",
"pinia": "^3.0.4", "pinia": "^3.0.4",
"vue": "^3.5.32", "vue": "^3.5.32",
"vue-router": "^4.6.4" "vue-router": "^4.6.4"
@@ -8522,6 +8523,15 @@
"node": ">=12" "node": ">=12"
} }
}, },
"node_modules/lucide-vue-next": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/lucide-vue-next/-/lucide-vue-next-1.0.0.tgz",
"integrity": "sha512-V6SPvx1IHTj/UY+FrIYWV5faISsPSb8BnWSFDxAtezWKvWc9ZZ40PDrdu1/Qb5vg4lHWr1hs1BAMGVGm6V1Xdg==",
"license": "ISC",
"peerDependencies": {
"vue": ">=3.0.1"
}
},
"node_modules/magic-string": { "node_modules/magic-string": {
"version": "0.30.21", "version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",

View File

@@ -47,6 +47,7 @@
"bonjour-service": "^1.3.0", "bonjour-service": "^1.3.0",
"electron-squirrel-startup": "^1.0.1", "electron-squirrel-startup": "^1.0.1",
"element-plus": "^2.13.6", "element-plus": "^2.13.6",
"lucide-vue-next": "^1.0.0",
"pinia": "^3.0.4", "pinia": "^3.0.4",
"vue": "^3.5.32", "vue": "^3.5.32",
"vue-router": "^4.6.4" "vue-router": "^4.6.4"

View File

@@ -0,0 +1,30 @@
<template>
<component
:is="icon"
:size="size"
:color="color"
:stroke-width="strokeWidth"
class="lucide-icon"
/>
</template>
<script setup>
defineProps({
icon: {
type: Object, // 注意:这里接收的是 Lucide 图标组件对象
required: true,
},
size: {
type: [Number, String],
default: 24,
},
color: {
type: String,
default: 'currentColor',
},
strokeWidth: {
type: [Number, String],
default: 2,
},
});
</script>

View File

@@ -6,14 +6,16 @@ import 'element-plus/dist/index.css';
import router from './router'; import router from './router';
import App from './App.vue'; import App from './App.vue';
import './style.css'; import './style.css';
import AppIcon from './components/base/AppIcon.vue';
const app = createApp(App); const app = createApp(App);
// 注册所有 Element Plus 图标 // 注册所有 Element Plus 图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) { for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component); app.component(key, component);
} }
// 注册自定义图标组件
app.component('AppIcon', AppIcon);
app.use(createPinia()); app.use(createPinia());
app.use(router); app.use(router);
app.use(ElementPlus); app.use(ElementPlus);

View File

@@ -8,6 +8,8 @@
<span class="emoji">👋</span> <span class="emoji">👋</span>
</h1> </h1>
<p class="welcome-subtitle">准备好开始今天的创作了吗</p> <p class="welcome-subtitle">准备好开始今天的创作了吗</p>
<AppIcon :icon="User" color="red" />
<AppIcon :icon="Rocket" :size="30" class="hover:text-red-500" />
</div> </div>
</div> </div>
@@ -98,73 +100,74 @@
</template> </template>
<script setup> <script setup>
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router';
import { import { User, Rocket } from 'lucide-vue-next';
Document, import {
Plus, Document,
FolderOpened, Plus,
Setting, FolderOpened,
Upload, Setting,
Top, Upload,
Bottom, Top,
Grid, Bottom,
Grid,
Clock, Clock,
Timer, Timer,
VideoCamera VideoCamera,
} from '@element-plus/icons-vue' } from '@element-plus/icons-vue';
const router = useRouter() const router = useRouter();
const stats = [ const stats = [
{ {
label: '文件总数', label: '文件总数',
value: '128', value: '128',
trend: 12, trend: 12,
icon: Document, icon: Document,
color: '#409EFF' color: '#409EFF',
}, },
{ {
label: '今日编辑', label: '今日编辑',
value: '24', value: '24',
trend: -3, trend: -3,
icon: Timer, icon: Timer,
color: '#67C23A' color: '#67C23A',
}, },
{ {
label: '运行次数', label: '运行次数',
value: '56', value: '56',
trend: 8, trend: 8,
icon: VideoCamera, icon: VideoCamera,
color: '#E6A23C' color: '#E6A23C',
}, },
] ];
const actions = [ const actions = [
{ {
label: '新建文件', label: '新建文件',
icon: Plus, icon: Plus,
color: '#409EFF', color: '#409EFF',
onClick: () => router.push('/editor') onClick: () => router.push('/editor'),
}, },
{ {
label: '打开文件', label: '打开文件',
icon: FolderOpened, icon: FolderOpened,
color: '#67C23A', color: '#67C23A',
onClick: () => {} onClick: () => {},
}, },
{ {
label: '导入项目', label: '导入项目',
icon: Upload, icon: Upload,
color: '#E6A23C', color: '#E6A23C',
onClick: () => {} onClick: () => {},
}, },
{ {
label: '系统设置', label: '系统设置',
icon: Setting, icon: Setting,
color: '#F56C6C', color: '#F56C6C',
onClick: () => {} onClick: () => {},
}, },
] ];
const recents = [ const recents = [
{ name: 'main.js', path: '/src/main', time: '2 分钟前' }, { name: 'main.js', path: '/src/main', time: '2 分钟前' },
@@ -172,11 +175,11 @@ const recents = [
{ name: 'index.css', path: '/src/renderer', time: '昨天' }, { name: 'index.css', path: '/src/renderer', time: '昨天' },
{ name: 'forge.config.js', path: '/', time: '3 天前' }, { name: 'forge.config.js', path: '/', time: '3 天前' },
{ name: 'package.json', path: '/', time: '5 天前' }, { name: 'package.json', path: '/', time: '5 天前' },
] ];
const handleFileClick = (item) => { const handleFileClick = (item) => {
console.log('点击文件:', item) console.log('点击文件:', item);
} };
</script> </script>
<style scoped> <style scoped>
@@ -209,7 +212,7 @@ const handleFileClick = (item) => {
} }
.greeting { .greeting {
background: linear-gradient(90deg, #409EFF 0%, #67C23A 100%); background: linear-gradient(90deg, #409eff 0%, #67c23a 100%);
-webkit-background-clip: text; -webkit-background-clip: text;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background-clip: text; background-clip: text;
@@ -285,11 +288,11 @@ const handleFileClick = (item) => {
} }
.stat-trend.up { .stat-trend.up {
color: #67C23A; color: #67c23a;
} }
.stat-trend.down { .stat-trend.down {
color: #F56C6C; color: #f56c6c;
} }
/* 主要内容区 */ /* 主要内容区 */
@@ -390,7 +393,7 @@ const handleFileClick = (item) => {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
flex-shrink: 0; flex-shrink: 0;
color: #409EFF; color: #409eff;
} }
.file-info { .file-info {
@@ -419,7 +422,7 @@ const handleFileClick = (item) => {
.file-time { .file-time {
font-size: 12px; font-size: 12px;
color: #C0C4CC; color: #c0c4cc;
flex-shrink: 0; flex-shrink: 0;
} }
</style> </style>