自定义卡片组件
Custom Card
- Create the Card Component
Create a file at .vitepress/theme/components/vcard.vue. This design uses a modern, elevated style with a hover effect and support for images.
<script setup>
defineProps({
title: String,
description: String,
link: String,
image: String
})
</script>
<template>
<a :href="link" class="custom-card">
<div v-if="image" class="card-image" :style="{ backgroundImage: `url(${image})` }"></div>
<div class="card-content">
<h3 class="card-title">{{ title }}</h3>
<p class="card-desc">{{ description }}</p>
</div>
</a>
</template>
<style scoped>
.custom-card {
display: block;
border: 1px solid var(--vp-c-bg-soft);
border-radius: 12px;
background-color: var(--vp-c-bg-soft);
transition: transform 0.2s, border-color 0.2s;
text-decoration: none !important;
overflow: hidden;
}
.custom-card:hover {
transform: translateY(-4px);
border-color: var(--vp-c-brand-1);
}
.card-image {
height: 160px;
background-size: cover;
background-position: center;
}
.card-content {
padding: 1.5rem;
}
.card-title {
margin: 0 0 0.5rem 0;
color: var(--vp-c-text-1);
}
.card-desc {
margin: 0;
font-size: 0.9rem;
color: var(--vp-c-text-2);
}
</style>- Register Globally
To use this component in any .md file, register it in .vitepress/theme/index.js (or .ts).
import DefaultTheme from 'vitepress/theme'
import vcard from './components/vcard.vue'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
// Register the component globally
app.component('vcard', vcard)
}
}- Use in Markdown
Now you can drop the card anywhere in your documentation. Make sure to use PascalCase for the component tag to avoid hydration issues.
<vcard
title="API Reference"
description="Explore our comprehensive API documentation."
link="/api/"
image="/hero-bg.png"
/>Grid Container
- Create the Grid Component
Save this as .vitepress/theme/components/vgrid.vue. It uses a so you can nest your vcard components inside it in Markdown.
<template>
<div class="card-grid">
<slot />
</div>
</template>
<style scoped>
.card-grid {
display: grid;
/* Adjust 250px to your preferred minimum card width */
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
margin-top: 2rem;
}
@media (max-width: 640px) {
.card-grid {
grid-template-columns: 1fr;
gap: 1rem;
}
}
</style>- Register Globally
Update your .vitepress/theme/index.js to include the new grid component:
import DefaultTheme from 'vitepress/theme'
import vcard from './components/vcard.vue'
import vgrid from './components/vgrid.vue'
export default {
extends: DefaultTheme,
enhanceApp({ app }) {
app.component('vcard', vcard)
app.component('vgrid', vgrid)
}
}- Usage in Markdown
You can now wrap multiple cards in the grid. VitePress will render them side-by-side.
<vgrid>
<vcard
title="Getting Started"
description="Learn how to install and configure the project."
link="/guide/getting-started"
/>
<vcard
title="Components"
description="Browse the library of pre-built UI components."
link="/guide/components"
/>
<vcard
title="Advanced"
description="Deep dive into customization and internals."
link="/guide/advanced"
/>
</vgrid>