Skip to content

Custom Component

About 309 wordsAbout 1 min

测试component

2024-12-11

VuePress pages are Vue applications under the hood, so Vue components can be used directly in Markdown. This article shows how to create, register and use a custom component with the plume theme — the colored cards on this page are the final result.

1. Create the component

Create DemoCard.vue under docs/.vuepress/theme/components/:

<script setup>
defineProps({
  title: { type: String, default: '' },
  color: { type: String, default: '#2a9dff' },
})
</script>

<template>
  <div class="demo-card" :style="{ '--demo-card-color': color }">
    <p v-if="title" class="demo-card-title">{{ title }}</p>
    <div class="demo-card-body">
      <slot />
    </div>
  </div>
</template>

<style scoped>
.demo-card {
  margin: 16px 0;
  padding: 14px 18px;
  border: 1px solid var(--demo-card-color);
  border-left-width: 4px;
  border-radius: 8px;
}
</style>

The component accepts title and color props, and receives nested content written in Markdown through <slot />.

2. Register the component

Register it globally in docs/.vuepress/client.ts:

import { defineClientConfig } from 'vuepress/client'
import DemoCard from './theme/components/DemoCard.vue'

export default defineClientConfig({
  enhance({ app }) {
    app.component('DemoCard', DemoCard)
  },
})

3. Use it in Markdown

Once registered, the component tag can be used directly in any Markdown file:

<DemoCard title="This is a custom component" color="#8b5cf6">
It works right inside Markdown, with `props` and slots.
</DemoCard>

Actual rendered result:

This is a custom component

It works right inside Markdown, with `props` and slots.

Try another color

The `color` prop changes the accent color of the card.

Notes

  • Prefer PascalCase component names (e.g. DemoCard) to avoid conflicts with native HTML tags
  • Styles declared with scoped stay inside the component and won't leak into the page
  • To use global state (such as route info) inside the component, install plugins in the enhance hook or import the composables provided by vuepress/client

Notice

Dear readers,

Thank you for your continuous attention and support for my blog! In order to share my thoughts and creations more effectively, I am constantly working on improving the content. However, this process involves the use of tools such as Google Translate and AI, so you may occasionally come across expressions that are not perfectly accurate.

I understand that for some readers, the English version is an important way to access the content. I am working hard to supplement and refine these materials as soon as possible. Meanwhile, if there are specific articles or topics that need to be prioritized for translation, please feel free to leave a comment, and I will do my best to meet your needs!

Thank you for your understanding and patience. I will continue to create valuable content and provide a richer reading experience for you. I look forward to each exchange with you here!